meshlab-1.3.2+dfsg1/0000755000175000017500000000000012227522351013057 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/0000755000175000017500000000000012227522351014325 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/0000755000175000017500000000000012227522351015270 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/plyrefine/0000755000175000017500000000000012227522351017265 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/plyrefine/main.cpp0000644000175000017500000001133511551320500020707 0ustar gladkgladk // mesh definition #include #include #include #include #include #include #include // input output #include #include // std #include using namespace vcg; using namespace std; struct MyFace; struct MyTetra; struct MyEdge; struct MyVertex: public VertexAFVNf{}; struct MyFace: public FaceAF{}; struct MyMesh: public tri::TriMesh< vector, vector >{}; #define FLAT 0 #define ARC 1 #define BUTTERFLY 2 //#define BUTTERFLY2 3 //#define PLANE 4 //#define SPHERE 5 #define LENGTH 6 #define ONLY_SEL 7 int main(int argc, char **argv){ if(argc<4) { printf( "\n PlyRefine ("__DATE__")\n" " Visual Computing Group I.S.T.I. C.N.R.\n" "Usage: PlyRefine filein.ply fileout.ply [command list]\n" "Commands: \n" " Refinement rules:\n" " -m# midpoint flat \n" " -a# midpoint arc\n" " -b# butterfly\n" //" -p# clip with plane \n" //" -s# clip with sphere \n" " Selective Refinement\n" " -L# refine only if the the edge is longer than #(default 0.0)\n" " -S(0|1) refine only selected faces\n" ); exit(0); } typedef pair OP_TYPE; vector operations; bool only_selected=false; int i=3; int n_steps;float length=0; while(i::Open(m,argv[1])!=0) { printf("Error reading file %s\n",argv[1]); exit(0); } vcg::tri::UpdateTopology::FaceFace(m); vcg::tri::UpdateTopology::FaceBorderFlags(m); vcg::tri::UpdateNormals::PerVertexNormalized(m); int h; for(i=0;i < operations.size();++i){ switch(operations[i].first){ case FLAT: for(h=0;h(),length,only_selected); } break; case ARC: for(h=0;h(),length,only_selected);} break; case BUTTERFLY: for(h=0;h(),length,only_selected); } break; //case BUTTERFLY2: // for(h=0;h(),length,only_selected); // } // break; /* case PLANE: for(h=0;h(),length,only_selected); } break; case SPHERE: for(h=0;h(),length,only_selected); } break; */ case LENGTH: length = operations[i].second; break; case ONLY_SEL: only_selected = (bool)operations[i].second; break; } } //m.ComputeNormalizedVertexNormal(); //Refine(m,MidPointArc(),0); vcg::tri::io::PlyInfo pi; vcg::tri::io::ExporterPLY::Save(m,argv[2],pi.mask); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/0000755000175000017500000000000012227522351016551 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/img_filters/0000755000175000017500000000000012227522351021055 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/img_filters/img_filters.cpp0000755000175000017500000002134211517500567024100 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2009 \/)\/ * * 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. * * * ****************************************************************************/ #include #include "wrap/qt/img_qt.h" void sample001_open_save_color(QString input_file, QString output_file) { img::Image<> image; img::openQtRGB(input_file, image); img::saveQtRGB(image, output_file); } void sample002_open_save_grayscale(QString input_file, QString output_file) { img::Image<1> image; img::openQtY(input_file, image); img::saveQtY(image, output_file); } void sample003_normalize(QString input_file, QString output_file) { img::Image<> image; img::openQtRGB(input_file, image); img::saveQtRGB(img::getNormalized(image), output_file); } void sample004_boxfilter(QString input_file, QString output_file) { img::Image<> image; img::openQtRGB(input_file, image); int radius=3; img::saveQtRGB(img::getBoxFiltered(image,radius), output_file); } void sample005_gaussiansmooth(QString input_file, QString output_file) { img::Image<> image; img::openQtRGB(input_file, image); int radius=4; img::saveQtRGB(img::getGaussianSmoothed(image,radius), output_file); } void sample006_medianfilter(QString input_file, QString output_file) { img::Image<> image; img::openQtRGB(input_file, image); int radius=5; img::saveQtRGB(img::getMedianFiltered(image,radius), output_file); } void sample007_unsharpmask(QString input_file, QString output_file) { img::Image<> image; img::openQtRGB(input_file, image); int radius=4; double factor=0.6; img::saveQtRGB(img::getUnsharpMasked(image,radius,factor), output_file); } void sample008_laplacianfilter(QString input_file, QString output_file) { img::Image<> image; img::openQtRGB(input_file, image); img::Image<> laplacianfiltered; img::LaplacianFilter(image,laplacianfiltered); img::saveQtRGB(img::getNormalized(laplacianfiltered), output_file); } void sample009_logfilter(QString input_file, QString output_file) { img::Image<> image; img::openQtRGB(input_file, image); int radius=5; img::Image<> logfiltered; img::LoGFilter(image,logfiltered,radius); img::saveQtRGB(img::getNormalized(logfiltered), output_file); } void sample010_dogfilter(QString input_file, QString output_file) { img::Image<> image; img::openQtRGB(input_file, image); // must be radius1 < radius2 int radius1=2; int radius2=4; img::Image<> dogfiltered; img::DoGFilter(image,dogfiltered,radius1,radius2); img::saveQtRGB(img::getNormalized(dogfiltered), output_file); } void sample011_general_convolutions(QString input_file, QString output_dir,QString output_suffix) { img::Image<> image; img::openQtRGB(input_file, image); QVector< QPair< double*, QPair< QPair< int, int > , QString> > > mm; double *f; f=new double[9]; f[0]= 0.0f; f[1]= 0.0f; f[2]= 0.0f; f[3]=-1.0f; f[4]= 1.0f; f[5]= 0.0f; f[6]= 0.0f, f[7]= 0.0f; f[8]= 0.0f; mm.push_back(qMakePair(f,qMakePair(qMakePair(3,3),QString("edge_enhance")))); f=new double[9]; f[0]= 2.0f; f[1]= 0.0f; f[2]= 0.0f; f[3]= 0.0f; f[4]=-1.0f; f[5]= 0.0f; f[6]= 0.0f, f[7]= 0.0f; f[8]=-1.0f; mm.push_back(qMakePair(f,qMakePair(qMakePair(3,3),QString("embross")))); f=new double[15]; f[0] = 1.0f; f[1] = 2.0f; f[2] = 0.0f; f[3] = 2.0f; f[4] = 1.0f; f[5] = 1.0f; f[6] = 2.0f; f[7] =-18.0f; f[8] = 2.0f; f[9] = 1.0f; f[10]= 1.0f; f[11]= 2.0f; f[12]= 0.0f; f[13]= 2.0f; f[14]= 1.0f; mm.push_back(qMakePair(f,qMakePair(qMakePair(5,3),QString("my_vert_edges")))); f=new double[15]; f[0] = 1.0f; f[1] = 1.0f; f[2] = 1.0f; f[3] = 2.0f; f[4] = 2.0f; f[5] = 2.0f; f[6] = 0.0f; f[7] =-18.0f; f[8] = 0.0f; f[9] = 2.0f; f[10]= 2.0f; f[11]= 2.0f; f[12]= 1.0f; f[13]= 1.0f; f[14]= 1.0f; mm.push_back(qMakePair(f,qMakePair(qMakePair(3,5),QString("my_horiz_edges")))); QPair< double*, QPair< QPair< int, int > , QString> > m; foreach(m,mm){ double* matrix=m.first; int matrix_width=((m.second).first).first; int matrix_height=((m.second).first).second; QString matrix_name=(m.second).second; img::Image<> convolved; img::convolution(image,convolved,matrix,matrix_width,matrix_height); delete [] matrix; bool normalize=(img::minValue(convolved)<0.0f)||(img::maxValue(convolved)>=255.0f); QString output_file(output_dir+"/011_general_convolution_"+matrix_name+ "_"+(normalize?" normalized_":"")+output_suffix); if(normalize) img::saveQtRGB(img::getNormalized(convolved),output_file); else img::saveQtRGB(convolved,output_file); } } void img_filters(QString input_dir,QString image,QString output_dir) { QString input_file(input_dir+"/"+image); sample001_open_save_color(input_file, output_dir+"/001-open_save_color_"+image); sample002_open_save_grayscale(input_file, output_dir+"/002-open_save_grayscale_"+image); sample003_normalize(input_file, output_dir+"/003_normalize_"+image); sample004_boxfilter(input_file, output_dir+"/004_boxfilter_"+image); sample005_gaussiansmooth(input_file, output_dir+"/005_gaussiansmooth_"+image); sample006_medianfilter(input_file, output_dir+"/006_medianfilter_"+image); sample007_unsharpmask(input_file, output_dir+"/007_unsharpmask_"+image); sample008_laplacianfilter(input_file, output_dir+"/008_laplacianfilter_normalized_"+image); sample009_logfilter(input_file, output_dir+"/009_logfilter_normalized_"+image); sample010_dogfilter(input_file, output_dir+"/010_dogfilter_normalized_"+image); sample011_general_convolutions(input_file, output_dir,image); } bool clean_dir(QDir dir); // utility, unrelated with the sample int main(int argc,char ** argv) { if(argc<3) { printf("Usage: img_filters \n"); return 1; } printf("Executing img_filters over all images in \"%s\", ouput is in \"%s\"\n", argv[1], argv[2]); QString input_dir(argv[1]); QString output_dir(argv[2]); QStringList readable_image_extensions = QStringList() << "*.bmp" << "*.gif" << "*.jpg" << "*.jpeg" << "*.png" << "*.pbm" << "*.pgm" << "*.ppm" << "*.tiff" << "*.xbm" << "*.xpm"; QStringList image_list = QDir(input_dir).entryList(readable_image_extensions,QDir::Files|QDir::Readable,QDir::Name); assert(clean_dir(QDir(output_dir))); try { foreach(QString image, image_list) img_filters(input_dir,image,output_dir); } catch (img::ImageException& e) { qDebug() << "caught ImageException, message:" << e.message; } return 0; } bool clean_dir(QDir dir){ // utility, unrelated with the sample if(!dir.exists()){ qDebug() << QString("dir \"%1\" does not exists\n").arg(dir.path()); return false; } foreach(QString e,dir.entryList(QDir::NoDotAndDotDot|QDir::Dirs|QDir::Files)){ QFileInfo i(QString("%1/%2").arg(dir.path(),e)); if(i.isDir()){ if(!clean_dir(QDir(QString("%1/%2").arg(dir.path(),e)))){ qDebug() << QString("cannot clean \"%1/%2\"\n").arg(dir.path(),e); return false; } if(!dir.rmdir(e)){ qDebug() << QString("cannot remove \"%1/%2\"\n").arg(dir.path(),e); return false; } }else{ if(!dir.remove(e)){ qDebug() << QString("cannot remove \"%1/%2\"\n").arg(dir.path(),e); return false; } } } return true; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/img_filters/img_filters.pro0000644000175000017500000000077111517500567024116 0ustar gladkgladk# debugging CONFIG += debug # Base options TEMPLATE = app LANGUAGE = C++ # Executable name TARGET = img_filters # STL support is enabled CONFIG += stl # enable console CONFIG += console # Awful.. win32{ DEFINES += NOMINMAX } # The following define is needed in gcc to remove the asserts win32-g++:DEFINES += NDEBUG CONFIG(debug, debug|release) { win32-g++:release:DEFINES -= NDEBUG } #include current path INCLUDEPATH += . #include lib path INCLUDEPATH += ../../.. SOURCES += img_filters.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_refine/0000755000175000017500000000000012227522351021554 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_refine/trimesh_refine.cpp0000644000175000017500000000766111551320477025301 0ustar gladkgladk#include #include #include #include #include #include #include #include #include #include #include // input output #include #include // std #include using namespace vcg; using namespace std; class MyEdge; // dummy prototype never used class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::Normal3f, vertex::BitFlags >{}; class MyFace : public Face < MyUsedTypes, face::InfoOcf, face::FFAdjOcf, face::VertexRef, face::BitFlags > {}; class MyMesh : public vcg::tri::TriMesh< vector, face::vector_ocf > {}; #define FLAT 0 #define LOOP 1 #define CATMULL 2 #define BUTTERFLY 3 #define ONE_QUAD_X_EDGE 4 int main(int argc, char **argv) { if(argc<4) { printf( "\n PlyRefine ("__DATE__")\n" " Visual Computing Group I.S.T.I. C.N.R.\n" "Usage: PlyRefine filein.ply fileout.[ply|off|obj|...] ref_step [opt] \n" "Commands: \n" " Refinement rules:\n" " -m use simple midpoint subdivision (default) \n" " -b use butterfly subdivision scheme \n" " -l use loop subdivision scheme \n" " -o use one-quad-per-edge schema (*) \n" " -c use Catmull-Clark (*) \n" " -e# refine only if the the edge is longer than #(default 0.0)\n" "Info:\n" " (*) produces quad-only meshes, but updates topology only, \n" " and leaves geometry unaffected \n" ); exit(2); } int RefMode = FLAT ; int i=4; int n_steps; float length=0; while(i::Open(m,argv[1])!=0) { printf("Error reading file %s\n",argv[1]); exit(1); } m.face.EnableFFAdjacency(); tri::UpdateTopology::FaceFace(m); tri::UpdateFlags::FaceBorderFromFF(m); tri::UpdateNormals::PerVertexNormalized(m); printf("Input mesh vn:%i fn:%i\n",m.vn,m.fn); n_steps=atoi(argv[3]); for(i=0;i < n_steps;++i) { switch(RefMode) { case FLAT: Refine >(m,MidPoint(&m),length); break; case LOOP: tri::RefineOddEven, tri::EvenPointLoop >(m, tri::OddPointLoop(), tri::EvenPointLoop(), length); break; case CATMULL: tri::BitQuadCreation::MakePureByCatmullClark(m); tri::UpdateNormals::PerBitQuadFaceNormalized(m); break; case ONE_QUAD_X_EDGE: tri::BitQuadCreation::MakePureByRefine(m); tri::UpdateNormals::PerBitQuadFaceNormalized(m); break; case BUTTERFLY: Refine >(m,MidPointButterfly(),length); break; } } printf("Output mesh vn:%i fn:%i\n",m.vn,m.fn); vcg::tri::io::PlyInfo pi; pi.mask|=vcg::tri::io::Mask::IOM_BITPOLYGONAL; vcg::tri::io::Exporter::Save(m,argv[2],pi.mask); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_refine/trimesh_refine.pro0000644000175000017500000000110211551320477025277 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### # To solve issue related to slash vs. backslash under cygwin try: # env MINGW_IN_SHELL=1 qmake -spec win32-g++ TARGET = trimesh_refine DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_refine.cpp ../../../wrap/ply/plylib.cpp # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_QT/0000755000175000017500000000000012227522351020630 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_QT/mainwindow.cpp0000644000175000017500000000605211517500567023521 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2007 \/)\/ * * 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 #include "mainwindow.h" MainWindow::MainWindow (QWidget * parent):QMainWindow (parent) { ui.setupUi (this); //connections //from toolFrame to glArea connect (ui.drawModeComboBox, SIGNAL (currentIndexChanged(int)), ui.glArea, SLOT (selectDrawMode(int))); connect (ui.loadTetrahedronPushButton, SIGNAL (clicked()), ui.glArea, SLOT (loadTetrahedron())); connect (ui.loadDodecahedronPushButton, SIGNAL (clicked()), ui.glArea, SLOT (loadDodecahedron())); //from toolFrame to glArea through mainwindow connect (ui.loadMeshPushButton, SIGNAL (clicked()), this, SLOT (chooseMesh())); connect (this, SIGNAL (loadMesh(QString)), ui.glArea, SLOT(loadMesh(QString))); //from glArea to statusbar connect (ui.glArea, SIGNAL (setStatusBar(QString)), ui.statusbar, SLOT (showMessage(QString))); } // mesh chooser file dialog void MainWindow::chooseMesh() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open Mesh"), QDir::currentPath(), tr("Poly Model (*.ply)")); if(!fileName.isEmpty()) emit loadMesh(fileName); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_QT/trimesh_qt.pro0000644000175000017500000000135011517500567023536 0ustar gladkgladk# Base options TEMPLATE = app LANGUAGE = C++ # QT modules QT += opengl # Executable name TARGET = trimesh_qt # Directories DESTDIR = . UI_DIR = build/ui MOC_DIR = build/moc OBJECTS_DIR = build/obj # Lib headers INCLUDEPATH += . INCLUDEPATH += ../../.. # Lib sources SOURCES += ../../../wrap/ply/plylib.cpp SOURCES += ../../../wrap/gui/trackball.cpp SOURCES += ../../../wrap/gui/trackmode.cpp # Compile glew DEFINES += GLEW_STATIC INCLUDEPATH += ../../../../code/lib/glew/include SOURCES += ../../../../code/lib/glew/src/glew.c # Awful problem with windows.. win32{ DEFINES += NOMINMAX } # Input HEADERS += mainwindow.h HEADERS += glarea.h SOURCES += main.cpp SOURCES += mainwindow.cpp SOURCES += glarea.cpp FORMS += mainwindow.ui meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_QT/glarea.h0000644000175000017500000001026311551320477022242 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2007 \/)\/ * * 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.1 2007/10/18 08:52:06 benedetti Initial release. ****************************************************************************/ #ifndef GLAREA_H_ #define GLAREA_H_ /// Opengl related imports #include #include /// vcg imports #include #include #include #include #include #include /// wrapper imports #include #include #include /// declaring edge and face type using namespace vcg; class CFace; class CVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsFaceType>{}; /// compositing wanted proprieties class CVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags>{}; class CFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags > {}; class CMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; class GLArea:public QGLWidget { Q_OBJECT public: GLArea (QWidget * parent = 0); /// we choosed a subset of the avaible drawing modes enum DrawMode{SMOOTH=0,POINTS,WIRE,FLATWIRE,HIDDEN,FLAT}; public slots: /// widget-based user interaction slots void selectDrawMode(int mode); void loadMesh(QString filename); void loadTetrahedron(); void loadDodecahedron(); signals: /// signal for setting the statusbar message void setStatusBar(QString message); protected: /// opengl initialization and drawing calls void initializeGL (); void resizeGL (int w, int h); void paintGL (); /// keyboard and mouse event callbacks void keyReleaseEvent(QKeyEvent * e); void keyPressEvent(QKeyEvent * e); void mousePressEvent(QMouseEvent*e); void mouseMoveEvent(QMouseEvent*e); void mouseReleaseEvent(QMouseEvent*e); void wheelEvent(QWheelEvent*e); private: /// the active mesh instance CMesh mesh; /// the active mesh opengl wrapper vcg::GlTrimesh glWrap; /// the active manipulator vcg::Trackball track; /// the current drawmode DrawMode drawmode; /// mesh data structure initializer void initMesh(QString message); }; #endif /*GLAREA_H_ */ meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_QT/glarea.cpp0000644000175000017500000001415111517500567022577 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2007 \/)\/ * * 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.1 2007/10/18 08:52:06 benedetti Initial release. ****************************************************************************/ #include #include "glarea.h" #include GLArea::GLArea (QWidget * parent) :QGLWidget (parent) { drawmode= SMOOTH; GLArea::loadTetrahedron(); } void GLArea::selectDrawMode(int mode){ drawmode=DrawMode(mode); updateGL(); } void GLArea::loadMesh(QString fileName) { int err=vcg::tri::io::ImporterPLY::Open(mesh,(fileName.toStdString()).c_str()); if(err!=0){ const char* errmsg=vcg::tri::io::ImporterPLY::ErrorMsg(err); QMessageBox::warning(this,tr("Error Loading Mesh"),QString(errmsg)); } initMesh("Loaded \""+fileName+"\"."); } void GLArea::loadTetrahedron(){ vcg::tri::Tetrahedron(mesh); initMesh(tr("Tethraedron [builtin]")); } void GLArea::loadDodecahedron(){ vcg::tri::Dodecahedron(mesh); initMesh(tr("Dodecahedron [builtin]")); } void GLArea::initMesh(QString message) { // update bounding box vcg::tri::UpdateBounding::Box(mesh); // update Normals vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(mesh); vcg::tri::UpdateNormals::PerFaceNormalized(mesh); // Initialize the opengl wrapper glWrap.m = &mesh; glWrap.Update(); updateGL(); emit setStatusBar(message); } void GLArea::initializeGL () { glClearColor(0, 0, 0, 0); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); } void GLArea::resizeGL (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); initializeGL(); } void GLArea::paintGL () { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40, GLArea::width()/(float)GLArea::height(), 0.1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,5, 0,0,0, 0,1,0); track.center=vcg::Point3f(0, 0, 0); track.radius= 1; track.GetView(); track.Apply(false); glPushMatrix(); float d=1.0f/mesh.bbox.Diag(); vcg::glScale(d); glTranslate(-glWrap.m->bbox.Center()); // the trimesh drawing calls switch(drawmode) { case SMOOTH: glWrap.Draw (); break; case POINTS: glWrap.Draw (); break; case WIRE: glWrap.Draw (); break; case FLATWIRE: glWrap.Draw (); break; case HIDDEN: glWrap.Draw (); break; case FLAT: glWrap.Draw (); break; default: break; } glPopMatrix(); track.DrawPostApply(); } void GLArea::keyReleaseEvent (QKeyEvent * e) { e->ignore (); if (e->key () == Qt::Key_Control) track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ControlModifier)); if (e->key () == Qt::Key_Shift) track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ShiftModifier)); if (e->key () == Qt::Key_Alt) track.ButtonUp (QT2VCG (Qt::NoButton, Qt::AltModifier)); updateGL (); } void GLArea::keyPressEvent (QKeyEvent * e) { e->ignore (); if (e->key () == Qt::Key_Control) track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ControlModifier)); if (e->key () == Qt::Key_Shift) track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ShiftModifier)); if (e->key () == Qt::Key_Alt) track.ButtonDown (QT2VCG (Qt::NoButton, Qt::AltModifier)); updateGL (); } void GLArea::mousePressEvent (QMouseEvent * e) { e->accept (); setFocus (); track.MouseDown (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ())); updateGL (); } void GLArea::mouseMoveEvent (QMouseEvent * e) { if (e->buttons ()) { track.MouseMove (e->x (), height () - e->y ()); updateGL (); } } void GLArea::mouseReleaseEvent (QMouseEvent * e) { track.MouseUp (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ())); updateGL (); } void GLArea::wheelEvent (QWheelEvent * e) { const int WHEEL_STEP = 120; track.MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ())); updateGL (); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_QT/mainwindow.ui0000644000175000017500000001175111517500567023356 0ustar gladkgladk mainWindow 0 0 715 579 Trimesh QT 9 6 0 0 0 0 QFrame::StyledPanel QFrame::Raised 9 6 Draw &Mode : drawModeComboBox Smooth Points Wire Flat Wire Hidden Flat Qt::Horizontal 40 20 Load &Mesh Load &Tetrahedron Load &Dodecahedron Qt::Horizontal 20 40 QFrame::StyledPanel QFrame::Raised 9 6 320 240 0 0 715 21 GLArea QWidget
glarea.h
drawModeComboBox loadMeshPushButton loadTetrahedronPushButton loadDodecahedronPushButton
meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_QT/mainwindow.h0000644000175000017500000000430411517500567023164 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2007 \/)\/ * * 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 MAINWINDOW_H_ #define MAINWINDOW_H_ #include "ui_mainwindow.h" class MainWindow:public QMainWindow { Q_OBJECT public: MainWindow(QWidget * parent = 0); public slots: void chooseMesh(); signals: void loadMesh(QString newMesh); private: Ui::mainWindow ui; }; #endif /*MAINWINDOW_H_ */ meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_QT/main.cpp0000644000175000017500000000450011517500567022265 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2007 \/)\/ * * 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 $ ****************************************************************************/ /** * Minimal QT trimesh viewer * * This sample shows how to use togheter: * - the Opengl module in QT using the designer * - the trimesh loading and initialization * - basic usage of the default manipulators (the "Trackball") */ #include #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow *mw = new MainWindow; mw->show(); return app.exec(); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_diskparam/0000755000175000017500000000000012227522351022257 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_diskparam/trimesh_diskparam.cpp0000644000175000017500000000711311651236256026501 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2009 \/)\/ * * 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. * * * ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include using namespace vcg; using namespace std; class MyEdge; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsEdgeType, Use ::AsFaceType>{}; class MyVertex : public Vertex{}; class MyFace : public Face< MyUsedTypes, face::VertexRef, face::BitFlags, face::FFAdj , face::WedgeTexCoord2f> {}; class MyEdge : public Edge{}; class MyMesh : public tri::TriMesh< vector, vector , vector > {}; int main( int argc, char **argv ) { MyMesh m; if(argc < 2 ) return -1; printf("Reading %s\n",argv[1]); int ret= tri::io::ImporterPLY::Open(m,argv[1]); if(ret!=0) { printf("Unable to open %s for '%s'\n",argv[1],tri::io::ImporterPLY::ErrorMsg(ret)); return -1; } printf("Mesh has %i vn %i fn\n",m.vn,m.fn); tri::PoissonSolver PS(m); if(!PS.IsFeaseable()) { printf("mesh is not homeomorphic to a disk\n"); return -1; } else printf("OK - mesh is homeomorphic to a disk\n"); PS.Init(); PS.SetBorderAsFixed(); PS.FixDefaultVertices(); PS.SolvePoisson(true); tri::UpdateTexture::WedgeTexFromVertexTex(m); tri::io::ExporterPLY::Save(m,"pippo.ply",tri::io::Mask::IOM_WEDGTEXCOORD); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_diskparam/trimesh_diskparam.pro0000644000175000017500000000045011651236256026514 0ustar gladkgladk#DEFINES += VCG_USE_EIGEN TARGET = trimesh_diskparam DEPENDPATH += . ../../.. INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_diskparam.cpp ../../../wrap/ply/plylib.cpp # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_optional/0000755000175000017500000000000012227522351022131 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_optional/trimesh_optional.pro0000644000175000017500000000075511551320477026246 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### # To solve issue related to slash vs. backslash under cygwin try: # env MINGW_IN_SHELL=1 qmake -spec win32-g++ TARGET = trimesh_optional DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_optional.cpp ../../../wrap/ply/plylib.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_optional/trimesh_optional_ocf.cpp0000644000175000017500000000213111551320477027045 0ustar gladkgladk#include #include #include #include #include #include #include class MyEdge; class MyFace; class MyVertex: public vcg::VertexSimp2{}; class MyFace: public vcg::FaceSimp2{}; class MyMesh: public vcg::tri::TriMesh< vcg::vert::vector_occ, std::vector >{}; int main() { MyMesh m; vcg::tri::Tetrahedron(m); MyMesh::VertexIterator vi = m.vert.begin(); (*vi).N() = vcg::Point3f(1.0,1.0,1.0); // ERROR m.vert.EnableAttribute(); // this allocate the memory to store the normal (*vi).N() = vcg::Point3f(1.0,1.0,1.0); // OK m.vert.DisableAttribute(); // this deallocate the memory to store the normal (*vi).N() = vcg::Point3f(1.0,1.0,1.0); // ERROR (again)! return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_optional/mesh_definition.h0000644000175000017500000000301111551320477025445 0ustar gladkgladk#ifndef _MESH_DEF_ #define _MESH_DEF_ #include #include #include #include #include #include class CFace; class CFaceOcf; class CVertex; class CVertexOcf; struct MyUsedTypes: public vcg::UsedTypes::AsVertexType,vcg::Use::AsFaceType>{}; struct MyUsedTypesOcf: public vcg::UsedTypes::AsVertexType,vcg::Use::AsFaceType>{}; // Optional stuff has two suffixes: // OCF Optional Component Fast // OCC Optional Component Compact class CVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::BitFlags,vcg::vertex::Normal3f >{}; class CVertexOcf : public vcg::Vertex< MyUsedTypesOcf,vcg::vertex::InfoOcf,vcg::vertex::Coord3f,vcg::vertex::QualityfOcf, vcg::vertex::BitFlags,vcg::vertex::Normal3f,vcg::vertex::RadiusfOcf >{}; class CFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VertexRef, vcg::face::BitFlags, vcg::face::Normal3f > {}; class CFaceOcf : public vcg::Face< MyUsedTypesOcf, vcg::face::InfoOcf, vcg::face::FFAdjOcf, vcg::face::VertexRef, vcg::face::BitFlags, vcg::face::Normal3fOcf > {}; class CMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; class CMeshOcf : public vcg::tri::TriMesh< vcg::vertex::vector_ocf, vcg::face::vector_ocf > {}; #endif meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_optional/trimesh_optional.cpp0000644000175000017500000000451211651743672026232 0ustar gladkgladk#include #include #include "mesh_definition.h" #include #include #include #include #include #include #include using namespace vcg; using namespace std; int main(int , char **) { CMesh cm; CMeshOcf cmof; tri::Tetrahedron(cm); tri::Tetrahedron(cmof); printf("Generated mesh has %i vertices and %i triangular faces\n",cm.vn,cm.fn); /// Calculates both vertex and face normals. /// The normal of a vertex v is the weigthed average of the normals of the faces incident on v. /// normals are not normalized cmof.face.EnableFFAdjacency(); vcg::tri::UpdateTopology::FaceFace(cm); vcg::tri::UpdateTopology::FaceFace(cmof); vcg::tri::UpdateFlags::FaceBorderFromFF(cm); vcg::tri::UpdateFlags::FaceBorderFromFF(cmof); vcg::tri::UpdateNormals::PerVertexNormalized(cm); vcg::tri::UpdateNormals::PerVertexNormalized(cmof); printf("Normal of face 0 is %f %f %f\n\n",cm.face[0].N()[0],cm.face[0].N()[1],cm.face[0].N()[2]); int t0=0,t1=0; while(t1-t0<200) { t0=clock(); Refine(cm,MidPointButterfly(),0); t1=clock(); Refine(cmof,MidPointButterfly(),0); } cmof.vert.EnableRadius(); cmof.vert.EnableQuality(); unsigned int hh = 0; for(CMeshOcf::VertexIterator vi = cmof.vert.begin(); vi!=cmof.vert.end();++vi,++hh){ if(hh%3==0) vcg::tri::Allocator::DeleteVertex(cmof,*vi); } for(CMeshOcf::VertexIterator vi = cmof.vert.begin(); vi!=cmof.vert.end();++vi) { if(!(*vi).IsD()) { float q =vi->Q(); float r =vi->R(); // int ii = vcg::tri::Index(cmof, *vi); assert(q==r); } } tri::Allocator::CompactVertexVector(cmof); tri::UpdateBounding::Box(cmof); for(CMeshOcf::VertexIterator vi = cmof.vert.begin(); vi!=cmof.vert.end();++vi) { if(!(*vi).IsD()) { float q =vi->Q(); float r =vi->R(); // int ii = vcg::tri::Index(cmof, *vi); assert(q==r); } } return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_optional/trimesh_simpdata_simp.cpp0000644000175000017500000000232011551320477027223 0ustar gladkgladk#include #include #include #include #include #include #include #include class MyEdge; class MyFace; class MyVertex: public vcg::VertexSimp2{}; class MyFace: public vcg::FaceSimp2{}; class MyMesh: public vcg::tri::TriMesh< std::vector, std::vector > {}; int main() { MyMesh m; vcg::tri::Tetrahedron(m); vcg::SimpleTempData MyTempData(m.vert); MyTempData.Start(); // enable the user defined attribute (memory is allocated) MyMesh::VertexIterator vi; // declare the iterator over the vertices for(vi = m.vert.begin(); vi != m.vert.end(); ++vi) { MyTempData[*vi] = 10; // assign the value for the 'short' attribute MyTempData[vi] = 10; // you can pass the element or an iterator to it } MyTempData.Stop(); // disable the user defined attribute (memory is freed) return 0; }meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_optional/trimesh_optional_occ.cpp0000644000175000017500000000201211551320477027040 0ustar gladkgladk#include #include #include #include #include #include #include class MyEdge; class MyFace; class MyVertex: public vcg::VertexSimp2{}; class MyFace: public vcg::FaceSimp2{}; class MyMesh: public vcg::tri::TriMesh< vcg::vert::vector_ocf, std::vector >{}; int main() { MyMesh m; vcg::tri::Tetrahedron(m); MyMesh::VertexIterator vi = m.vert.begin(); (*vi).N() = vcg::Point3f(1.0,1.0,1.0); // ERROR m.vert.EnableNormal(); // this allocate the memory to store the normal (*vi).N() = vcg::Point3f(1.0,1.0,1.0); // OK m.vert.DisableNormal(); // this deallocate the memory to store the normal (*vi).N() = vcg::Point3f(1.0,1.0,1.0); // ERROR (again)! return 0; }meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_topology/0000755000175000017500000000000012227522351022160 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_topology/trimesh_topology.cpp0000644000175000017500000000460011551320500026262 0ustar gladkgladk#include #include #include #include #include #include // topology computation #include // half edge iterators #include using namespace vcg; class MyEdge; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags >{}; class MyFace : public Face < MyUsedTypes, face::VertexRef,face::FFAdj, face::Mark, face::BitFlags > {}; class MyMesh : public tri::TriMesh< std::vector, std::vector >{}; int main(int ,char ** ){ MyMesh m; //generate a mesh vcg::tri::Icosahedron(m); //update the face-face topology vcg::tri::UpdateTopology::FaceFace(m); // Now for each face the F() members are meaningful if(face::IsBorder(m.face[0],0)) printf("Edge 0 of face 0 is a border\n"); else printf("Edge 0 of face 0 is NOT a border\n"); // always this path! vcg::face::FFDetach(m.face[0],0); // Detach the face [0] from the mesh vcg::face::FFDetach(m.face[0],1); vcg::face::FFDetach(m.face[0],2); if(face::IsBorder(m.face[0],0)) printf("Edge 0 of face 0 is a border\n"); // always this path! else printf("Edge 0 of face 0 is NOT a border\n"); m.face[0].SetD(); // deleting face [0] (i.e. marked as deleted) // declare an iterator on the mesh vcg::face::Pos he, hei; // Now a simple search and trace of all the border of the mesh MyMesh::FaceIterator fi; UnMarkAll(m); int BorderEdgeNum=0; int HoleNum=0; for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) { for(int j=0;j<3;j++) { if ( face::IsBorder(*fi,j) && tri::IsMarked(m,&*fi)) { tri::Mark(m,&*fi); hei.Set(&*fi,j,fi->V(j)); he=hei; do { BorderEdgeNum++; he.NextB(); // next edge along a border tri::Mark(m,he.f); } while (he.f!=hei.f); HoleNum++; } } } printf("Mesh has %i holes and %i border edges\n",HoleNum,BorderEdgeNum); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_topology/trimesh_topology.pro0000644000175000017500000000053511551320500026303 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### TARGET = trimesh_topology DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_topology.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/aabb_binary_tree/0000755000175000017500000000000012227522351022021 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/aabb_binary_tree/aabb_binary_tree.cpp0000644000175000017500000001041611551320500025766 0ustar gladkgladk// standard headers #include // stl headers #include // vcg headers //#include //#include #include #include #include #include #include #include #include #include #include #include #include typedef float AScalarType; using namespace vcg; class AVertex; class AFace; struct MyUsedTypes : public vcg::UsedTypes< vcg::Use ::AsVertexType, vcg::Use ::AsFaceType>{}; class AVertex : public Vertex< MyUsedTypes, vertex::Normal3f, vertex::Coord3f,vertex::BitFlags >{}; class AFace : public Face< MyUsedTypes, face::VertexRef, face::Normal3f, face::EdgePlane, face::BitFlags> {}; //class AVertex : public vcg::Vertex< AScalarType, AEdge, AFace > { }; //class AFace : public vcg::FaceRTFMFN< AVertex, AEdge, AFace > { }; class AMesh : public vcg::tri::TriMesh< std::vector, std::vector > { }; typedef vcg::AABBBinaryTreeIndex AIndex; static AMesh gMesh; static AIndex gIndex; static void CreateMesh(void) { vcg::tri::Dodecahedron(gMesh); vcg::tri::UpdateFlags::Clear(gMesh); vcg::tri::UpdateNormals::PerVertexNormalized(gMesh); vcg::tri::UpdateEdges::Set(gMesh); } static void SetIndex(void) { gIndex.Set(gMesh.face.begin(), gMesh.face.end()); } static void TestClosest(void) { vcg::face::PointDistanceFunctor getPtDist; const AIndex::CoordType queryPoint((AIndex::ScalarType)0, (AIndex::ScalarType)0, (AIndex::ScalarType)0); const AIndex::ScalarType maxDist = std::numeric_limits::max(); AIndex::ObjPtr closestFace; AIndex::ScalarType closestDist; AIndex::CoordType closestPoint; vcg::EmptyClass a; closestFace = gIndex.GetClosest(getPtDist, a, queryPoint, maxDist, closestDist, closestPoint); printf("GetClosest Test:\n"); if (closestFace != 0) { printf("\tface : 0x%p\n", closestFace); printf("\tdistance : %f\n", closestDist); printf("\tpoint : [%f, %f, %f]\n", closestPoint[0], closestPoint[1], closestPoint[2]); } else { printf("\tno object found (index is probably empty).\n"); } } static void TestKClosest(void) { vcg::face::PointDistanceFunctor getPtDist; const unsigned int k = 10; const AIndex::CoordType queryPoint((AIndex::ScalarType)0, (AIndex::ScalarType)0, (AIndex::ScalarType)0); const AIndex::ScalarType maxDist = std::numeric_limits::max(); std::vector closestObjects; std::vector closestDistances; std::vector closestPoints; vcg::EmptyClass a; unsigned int rk = gIndex.GetKClosest(getPtDist, a, k, queryPoint, maxDist, closestObjects, closestDistances, closestPoints); printf("GetKClosest Test:\n"); printf("\tfound %d objects\n", rk); } static void TestRay(void) { const bool TEST_BACK_FACES = true; vcg::RayTriangleIntersectionFunctor rayIntersector; const AIndex::ScalarType maxDist = std::numeric_limits::max(); const AIndex::CoordType rayOrigin((AIndex::ScalarType)0, (AIndex::ScalarType)0, (AIndex::ScalarType)0); const AIndex::CoordType rayDirection((AIndex::ScalarType)1, (AIndex::ScalarType)0, (AIndex::ScalarType)0); const vcg::Ray3 ray(rayOrigin, rayDirection); AIndex::ObjPtr isectFace; AIndex::ScalarType rayT; AIndex::CoordType isectPt; vcg::EmptyClass a; isectFace = gIndex.DoRay(rayIntersector, a , ray, maxDist, rayT); printf("DoRay Test:\n"); if (isectFace != 0) { printf("\tface : 0x%p\n", isectFace); printf("\tray t : %f\n", rayT); } else { printf("\tno object found (index is probably empty).\n"); } } int main (int /*argc*/, char ** /*argv*/) { CreateMesh(); SetIndex(); printf("Spatial Index Tests\n"); printf("---\n"); TestClosest(); printf("---\n"); TestKClosest(); printf("---\n"); TestRay(); printf("---\n"); return (0); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/aabb_binary_tree/aabb_binary_tree.pro0000644000175000017500000000053211551320500026002 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### TARGET = aabb_binary_tree DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console TEMPLATE = app SOURCES += aabb_binary_tree.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_copy/0000755000175000017500000000000012227522351021256 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_copy/trimeshcopy.cpp0000644000175000017500000001017512005675121024332 0ustar gladkgladk // stuff to define the mesh #include #include #include #include #include #include // io #include #include #include #include #include #include class MyVertex; class MyEdge; class MyFace; struct MyUsedTypes: public vcg::UsedTypes::AsVertexType,vcg::Use::AsEdgeType,vcg::Use::AsFaceType>{}; class MyVertex : public vcg::Vertex< MyUsedTypes,vcg::vertex::VFAdj,vcg::vertex::Coord3f,vcg::vertex::Normal3f,vcg::vertex::Mark,vcg::vertex::BitFlags > { }; class MyEdge : public vcg::Edge< MyUsedTypes> {}; class MyFace : public vcg::Face< MyUsedTypes, vcg::face::VFAdj, vcg::face::VertexRef, vcg::face::BitFlags > {}; // the main mesh class class MyMesh : public vcg::tri::TriMesh, std::vector > {}; class OcfVertex; class OcfEdge; class OcfFace; // Declaration of the semantic of the used types class OcfUsedTypes: public vcg::UsedTypes < vcg::Use::AsVertexType, vcg::Use::AsEdgeType, vcg::Use::AsFaceType >{}; // The Main Vertex Class // Most of the attributes are optional and must be enabled before use. // Each vertex needs 40 byte, on 32bit arch. and 44 byte on 64bit arch. class OcfVertex : public vcg::Vertex< OcfUsedTypes,vcg::vertex::InfoOcf,vcg::vertex::Coord3f,vcg::vertex::BitFlags,vcg::vertex::Normal3fOcf,vcg::vertex::VFAdjOcf,vcg::vertex::MarkOcf> { }; // The Main Edge Class // Currently it does not contains anything. class OcfEdge : public vcg::Edge { }; // Each face needs 32 byte, on 32bit arch. and 48 byte on 64bit arch. class OcfFace : public vcg::Face< OcfUsedTypes,vcg::face::InfoOcf,vcg::face::VertexRef,vcg::face::BitFlags,vcg::face::VFAdjOcf> {}; class OcfMesh : public vcg::tri::TriMesh< vcg::vertex::vector_ocf, vcg::face::vector_ocf > { }; void Usage() { printf( "---------------------------------\n" " TriMeshCopy V.1.0 \n" " http://vcg.isti.cnr.it\n" " http://vcg.sourceforge.net\n" " release date: "__DATE__"\n" "---------------------------------\n\n" "TriMeshCopy 1.0 \n"__DATE__"\n" "Copyright 2003-2012 Visual Computing Lab I.S.T.I. C.N.R.\n" "\nUsage: "\ "trimeshcopy fileIn -(n|o) [fileOut]\n"\ "trimeshcopy test vcg::MeshCopy efficiency.\nIt imports a fileIn file into a user defined mesh and test how long vcg::MeshCopy needs to copy the imported mesh in a second one.The copy time is expressed in milliseconds.\nIf the -n flag is used a non-optional attributes mesh will be tested, defining -o, instead, the target mesh will be an ocf one.\nA fileOut file can be passed to the tool in order to check if the mesh was successfully copied.\nThe file will be exported in PLY file format.\n" ); exit(-1); } template bool UnitTest_Append(const char *filename1, const char *filename2) { MeshType mr; MeshType ml; int startOpen=clock(); int err=vcg::tri::io::Importer::Open(mr,filename1); if(err) { std::cerr << "Unable to open mesh " << filename1 << " : " << vcg::tri::io::Importer::ErrorMsg(err) << std::endl; exit(-1); } int endOpen = clock(); std::cout << "mesh loaded in " << float(endOpen-startOpen)/CLOCKS_PER_SEC << " msecs. Verts: " << mr.vn << " Faces: " << mr.fn << "\n"; int startCopy = clock(); vcg::tri::Append::Mesh(ml,mr,false,true); int endCopy = clock(); std::cout << "mesh copied in " << float(endCopy-startCopy)/CLOCKS_PER_SEC << " msecs." << std::endl; assert(ml.vn==mr.vn); assert(ml.en==mr.en); assert(ml.fn==mr.fn); int startSave = clock(); vcg::tri::io::ExporterPLY::Save(ml,filename2); int endSave = clock(); std::cout << "mesh saved in " << float(endSave-startSave)/CLOCKS_PER_SEC << " msecs." << std::endl; return true; } int main(int argc ,char**argv) { UnitTest_Append(argv[1],"out.ply"); UnitTest_Append(argv[1],"out.ply"); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_copy/trimeshcopy.pro0000644000175000017500000000043612005675121024347 0ustar gladkgladk TARGET = trimeshcopy DEPENDPATH += ../../.. INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app HEADERS += SOURCES += trimeshcopy.cpp ../../../wrap/ply/plylib.cpp #DEFINES += N_DEBUG # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_edge/0000755000175000017500000000000012227522351021210 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_edge/trimesh_edge.pro0000644000175000017500000000057111651743673024410 0ustar gladkgladkTARGET = trimesh_edge DEPENDPATH += . ../../.. INCLUDEPATH += . ../../.. CONFIG += console stl opengl TEMPLATE = app SOURCES += trimesh_edge.cpp ../../../wrap/ply/plylib.cpp HEADERS += ../../../vcg/complex/algorithms/update/topology.h HEADERS += ../../../wrap/gl/glu_tessellator_cap.h # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_edge/trimesh_edge.cpp0000644000175000017500000002062711651743673024376 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2009 \/)\/ * * 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. * * * ****************************************************************************/ #include #include #include #include #include #include #include #include #include // input output #include #include // topology computation #include #include #include #include #include // normals #include #include #include #include using namespace vcg; using namespace std; class MyEdge; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsEdgeType, Use ::AsFaceType>{}; class MyVertex : public Vertex{}; class MyFace : public Face< MyUsedTypes, face::FFAdj, face::VertexRef, face::BitFlags >{}; class MyEdge : public Edge{}; class MyMesh : public tri::TriMesh< vector, vector , vector > {}; void CapHole(MyMesh &m, MyMesh &capMesh, bool reverseFlag) { capMesh.Clear(); std::vector< std::vector > outlines; std::vector outline; tri::Allocator::CompactVertexVector(m); tri::Allocator::CompactFaceVector(m); tri::UpdateFlags::FaceClearV(m); tri::UpdateFlags::VertexClearV(m); tri::UpdateTopology::FaceFace(m); int nv=0; for(size_t i=0;i p(startB,j); assert(p.IsBorder()); do { assert(p.IsManifold()); p.F()->SetV(); outline.push_back(p.V()->P()); p.NextB(); nv++; } while(!p.F()->IsV()); if (reverseFlag) std::reverse(outline.begin(),outline.end()); outlines.push_back(outline); outline.clear(); } } if (nv<2) return; MyMesh::VertexIterator vi=vcg::tri::Allocator::AddVertices(capMesh,nv); for (size_t i=0;iP()=outlines[i][j]; } std::vector indices; glu_tesselator::tesselate(outlines, indices); std::vector points; glu_tesselator::unroll(outlines, points); MyMesh::FaceIterator fi=tri::Allocator::AddFaces(capMesh,nv-2); for (size_t i=0; iV(0)=&capMesh.vert[ indices[i+0] ]; (*&fi)->V(1)=&capMesh.vert[ indices[i+1] ]; (*&fi)->V(2)=&capMesh.vert[ indices[i+2] ]; } tri::Clean::RemoveDuplicateVertex(capMesh); tri::UpdateBounding::Box(capMesh); } bool SplitMesh(MyMesh &m, /// The mesh that has to be splitted. It is NOT changed MyMesh &A, MyMesh &B, /// The two resulting pieces, correct only if true is returned Plane3f plane) { tri::Append::Mesh(A,m); tri::UpdateQuality::VertexFromPlane(A, plane); QualityMidPointFunctor slicingfunc(0.0f); QualityEdgePredicate slicingpred(0.0f); tri::UpdateTopology::FaceFace(A); // The Actual Slicing RefineE, QualityEdgePredicate > (A, slicingfunc, slicingpred, false); tri::Append::Mesh(B,A); tri::UpdateSelection::VertexFromQualityRange(A,-std::numeric_limits::max(),0); tri::UpdateSelection::FaceFromVertexStrict(A); for(MyMesh::FaceIterator fi=A.face.begin();fi!=A.face.end();++fi) if(!(*fi).IsD() && (*fi).IsS() ) tri::Allocator::DeleteFace(A,*fi); tri::Clean::RemoveUnreferencedVertex(A); tri::UpdateSelection::VertexFromQualityRange(B,0,std::numeric_limits::max()); tri::UpdateSelection::FaceFromVertexStrict(B); for(MyMesh::FaceIterator fi=B.face.begin();fi!=B.face.end();++fi) if(!(*fi).IsD() && (*fi).IsS() ) tri::Allocator::DeleteFace(B,*fi); tri::Clean::RemoveUnreferencedVertex(B); tri::UpdateTopology::FaceFace(m); MyMesh Cap; CapHole(A,Cap,0); tri::Append::Mesh(A,Cap); CapHole(B,Cap,0); tri::Append::Mesh(B,Cap); tri::Clean::RemoveDuplicateVertex(A); tri::Clean::RemoveDuplicateVertex(B); return true; } void GetRandPlane(Box3f &bb, Plane3f &plane) { Point3f planeCenter = bb.Center(); Point3f planeDir = Point3f(-0.5f+float(rand())/RAND_MAX,-0.5f+float(rand())/RAND_MAX,-0.5f+float(rand())/RAND_MAX); planeDir.Normalize(); plane.Init(planeCenter+planeDir*0.3f*bb.Diag()*float(rand())/RAND_MAX,planeDir); } int main( int argc, char **argv ) { if(argc<2) { printf("Usage trimesh_base \n"); return -1; } MyMesh m, // The loaded mesh em, // the 2D polyline representing the section slice, // the planar mesh resulting from the triangulation of the above sliced; // the 3D mesh resulting by the actual slicing of m into two capped sub pieces if(tri::io::ImporterPLY::Open(m,argv[1])!=0) { printf("Error reading file %s\n",argv[1]); exit(0); } tri::UpdateBounding::Box(m); printf("Input mesh vn:%i fn:%i\n",m.vn,m.fn); srand(time(0)); Plane3f slicingPlane; GetRandPlane(m.bbox,slicingPlane); printf("slicing dir %5.2f %5.2f %5.2f\n",slicingPlane.Direction()[0],slicingPlane.Direction()[1],slicingPlane.Direction()[2]); vcg::IntersectionPlaneMesh(m, slicingPlane, em ); tri::Clean::RemoveDuplicateVertex(em); vcg::tri::CapEdgeMesh(em,slice); printf("Slice mesh has %i vert and %i faces\n", slice.vn, slice.fn ); MyMesh A,B; bool ret=SplitMesh(m,A,B,slicingPlane); tri::UpdatePosition::Translate(A, slicingPlane.Direction()*m.bbox.Diag()/80.0); tri::UpdatePosition::Translate(B,-slicingPlane.Direction()*m.bbox.Diag()/80.0); tri::Append::Mesh(sliced,A); tri::Append::Mesh(sliced,B); printf("Sliced mesh has %i vert and %i faces\n", sliced.vn, sliced.fn ); tri::io::ExporterPLY::Save(slice,"slice.ply",false); tri::io::ExporterPLY::Save(sliced,"sliced.ply",false); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_attribute/0000755000175000017500000000000012227522351022307 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_attribute/trimesh_attribute.pro0000644000175000017500000000077311551320477026602 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### # To solve issue related to slash vs. backslash under cygwin try: # env MINGW_IN_SHELL=1 qmake -spec win32-g++ TARGET = trimesh_attribute DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_attribute.cpp ../../../wrap/ply/plylib.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_attribute/trimesh_attribute.cpp0000644000175000017500000000555611551320477026570 0ustar gladkgladk #include #include #include #include #include #include class MyEdge; class MyFace; class MyVertex; struct MyUsedTypes : public vcg::UsedTypes< vcg::Use ::AsVertexType, vcg::Use ::AsFaceType>{}; class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f,vcg::vertex::Normal3f>{}; class MyFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f> {}; class MyMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; float Irradiance(MyMesh::VertexType v){ // ..... return 1.0; } int main() { MyMesh m; //...here m is filled // add a per-vertex attribute with type float named "Irradiance" MyMesh::PerVertexAttributeHandle ih = vcg::tri::Allocator::AddPerVertexAttribute (m,std::string("Irradiance")); // add a per-vertex attribute with type float named "Radiosity" vcg::tri::Allocator::AddPerVertexAttribute (m,std::string("Radiosity")); // add a per-vertex attribute with type bool and no name specified MyMesh::PerVertexAttributeHandle blocked_h = vcg::tri::Allocator::AddPerVertexAttribute (m); // add a per-vertex attribute with type bool and no name specified MyMesh::PerFaceAttributeHandle blocked_hf = vcg::tri::Allocator::AddPerFaceAttribute (m); MyMesh::VertexIterator vi; int i = 0; for(vi = m.vert.begin(); vi != m.vert.end(); ++vi,++i){ ih[vi] = Irradiance(*vi); // [] operator takes a iterator ih[*vi] = Irradiance(*vi); // or a MyMesh::VertexType object ih[&*vi]= Irradiance(*vi); // or a pointer to it ih[i] = Irradiance(*vi); // or an integer index } // Once created with AddPerVertexAttribute, an handle to the attribute can be obtained as follows MyMesh::PerVertexAttributeHandle rh = vcg::tri::Allocator::GetPerVertexAttribute(m,"Radiosity"); // you can query if an attribute is present or not bool hasRadiosity = vcg::tri::HasPerVertexAttribute(m,"Radiosity"); // you can delete an attibute by name vcg::tri::Allocator::DeletePerVertexAttribute(m,"Radiosity"); // you can delete an attibute by handle vcg::tri::Allocator::DeletePerVertexAttribute(m,blocked_h); bool res ; res = vcg::tri::Allocator::IsValidHandle(m,ih);printf("%d\n",res); res = vcg::tri::Allocator::IsValidHandle(m,blocked_hf);printf("%d\n",res); vcg::tri::Allocator::DeletePerVertexAttribute(m,ih); vcg::tri::Allocator::DeletePerFaceAttribute(m,blocked_hf); res = vcg::tri::Allocator::IsValidHandle(m,ih);printf("%d\n",res); res = vcg::tri::Allocator::IsValidHandle(m,blocked_hf);printf("%d\n",res); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_smooth/0000755000175000017500000000000012227522351021615 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_smooth/trimesh_smooth.cpp0000644000175000017500000000376111551320477025400 0ustar gladkgladk#include #include #include #include #include #include #include // to clean up a mesh #include #include // input output #include #include using namespace vcg; using namespace std; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::VFAdj, vertex::Coord3f, vertex::Normal3f, vertex::BitFlags >{}; class MyFace : public Face < MyUsedTypes, face::VFAdj, face::Normal3f, face::VertexRef, face::BitFlags > {}; class MyMesh : public vcg::tri::TriMesh, vector > {}; int main(int argc,char ** argv) { if(argc<4) { printf("Usage: trimesh_smooth \n"); return 0; } MyMesh m; //open a mesh int err = tri::io::Importer::Open(m,argv[1]); if(err) { // all the importers return 0 in case of success printf("Error in reading %s: '%s'\n",argv[1], tri::io::Importer::ErrorMsg(err)); exit(-1); } // some cleaning to get rid of bad file formats like stl that duplicate vertexes.. int dup = tri::Clean::RemoveDuplicateVertex(m); int unref = tri::Clean::RemoveUnreferencedVertex(m); printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,argv[1]); int Step= atoi(argv[2]); tri::UpdateTopology::VertexFace(m); for(int i=0;i::PerFaceNormalized(m); tri::Smooth::VertexCoordPasoDobleFast(m,atoi(argv[3]),atof(argv[4]),atoi(argv[5])); } //LaplacianSmooth(m,atoi(argv[2])); tri::io::ExporterPLY::Save(m,"out.ply"); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_smooth/trimesh_smooth.pro0000644000175000017500000000057011551320477025411 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### TARGET = trimesh_smooth DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_smooth.cpp ../../../wrap/ply/plylib.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_base/0000755000175000017500000000000012227522351021216 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_base/trimesh_definition.cpp0000644000175000017500000000107411551320500025576 0ustar gladkgladk#include #include #include #include #include #include class MyEdge; class MyFace; class MyVertex: public vcg::VertexSimp2{}; class MyFace: public vcg::FaceSimp2{}; class MyMesh: public vcg::tri::TriMesh< std::vector, std::vector > {}; int main() { MyMesh m; return 0; }meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_base/trimesh_base.cpp0000644000175000017500000000646511551320500024371 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2009 \/)\/ * * 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. * * * ****************************************************************************/ #include #include #include #include #include #include #include // input output #include #include // topology computation #include // normals #include using namespace vcg; using namespace std; class MyEdge; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsEdgeType, Use ::AsFaceType>{}; class MyVertex : public Vertex{}; class MyFace : public Face< MyUsedTypes, face::FFAdj, face::VertexRef, face::BitFlags > {}; class MyEdge : public Edge{}; class MyMesh : public tri::TriMesh< vector, vector , vector > {}; int main( int argc, char **argv ) { if(argc<2) { printf("Usage trimesh_base \n"); return -1; } MyMesh m; if(tri::io::ImporterPLY::Open(m,argv[1])!=0) { printf("Error reading file %s\n",argv[1]); exit(0); } tri::UpdateTopology::FaceFace(m); tri::UpdateFlags::FaceBorderFromFF(m); tri::UpdateNormals::PerVertexNormalized(m); printf("Input mesh vn:%i fn:%i\n",m.vn,m.fn); printf( "Mesh has %i vert and %i faces\n", m.vn, m.fn ); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_base/trimesh_base.pro0000644000175000017500000000071411551320500024376 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### TARGET = trimesh_base DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_base.cpp ../../../wrap/ply/plylib.cpp # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_hole/0000755000175000017500000000000012227522351021233 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_hole/trimesh_hole.cpp0000644000175000017500000001610211651236256024427 0ustar gladkgladk#include #include #include #include #include #include #include #include #include #include #include #include #include // topology computation #include #include #include // half edge iterators #include // input output #include #include using namespace vcg; using namespace std; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags, vertex::Normal3f, vertex::Mark, vertex::Color4b >{}; class MyFace : public Face < MyUsedTypes, face::VertexRef,face::FFAdj, face::Mark, face::BitFlags, face::Normal3f> {}; class MyMesh : public tri::TriMesh< vector, vector >{}; //Delaunay class MyDelaunayFlip: public vcg::tri::TriEdgeFlip< MyMesh, MyDelaunayFlip > { public: typedef vcg::tri::TriEdgeFlip< MyMesh, MyDelaunayFlip > TEF; inline MyDelaunayFlip( const TEF::PosType &p, int i,BaseParameterClass *pp) :TEF(p,i,pp){} }; bool callback(int percent, const char *str) { cout << "str: " << str << " " << percent << "%\r"; return true; } template bool NormalTest(typename face::Pos pos) { //giro intorno al vertice e controllo le normali typename MESH::ScalarType thr = 0.0f; typename MESH::CoordType NdP = vcg::Normal(*pos.f); typename MESH::CoordType tmp, oop, soglia = typename MESH::CoordType(thr,thr,thr); face::Pos aux=pos; do{ aux.FlipF(); aux.FlipE(); oop = Abs(tmp - ::vcg::Normal(*pos.f)); if(oop < soglia )return false; }while(aux != pos && !aux.IsBorder()); return true; } int main(int argc,char ** argv){ if(argc<5) { printf( "\n HoleFilling ("__DATE__")\n" "Visual Computing Group I.S.T.I. C.N.R.\n" "Usage: trimesh_hole #algorithm #size filein.ply fileout.ply \n" "#algorithm: \n" " 1) Trivial Ear \n" " 2) Minimum weight Ear \n" " 3) Selfintersection Ear \n" " 4) Minimum weight \n" ); exit(0); } int algorithm = atoi(argv[1]); int holeSize = atoi(argv[2]); if(algorithm < 0 && algorithm > 4) { printf("Error in algorithm's selection %i\n",algorithm); exit(0); } MyMesh m; if(tri::io::ImporterPLY::Open(m,argv[3])!=0) { printf("Error reading file %s\n",argv[2]); exit(0); } //update the face-face topology tri::UpdateTopology::FaceFace(m); tri::UpdateNormals::PerVertexPerFace(m); tri::UpdateFlags::FaceBorderFromFF(m); assert(tri::Clean::IsFFAdjacencyConsistent(m)); //compute the average of face area float AVG,sumA=0.0f; int numA=0,indice; indice = m.face.size(); MyMesh::FaceIterator fi; for(fi=m.face.begin();fi!=m.face.end();++fi) { sumA += DoubleArea(*fi)/2; numA++; for(int ind =0;ind<3;++ind) fi->V(ind)->InitIMark(); } AVG=sumA/numA; //tri::Hole holeFiller; switch(algorithm) { case 1: tri::Hole::EarCuttingFill >(m,holeSize,false); break; case 2: tri::Hole::EarCuttingFill >(m,holeSize,false,callback); break; case 3: tri::Hole::EarCuttingIntersectionFill >(m,holeSize,false); break; case 4: tri::Hole::MinimumWeightFill(m,holeSize, false); tri::UpdateTopology::FaceFace(m); break; } tri::UpdateFlags::FaceBorderFromFF(m); assert(tri::Clean::IsFFAdjacencyConsistent(m)); printf("\nStart refinig...\n"); /*start refining */ MyMesh::VertexIterator vi; MyMesh::FaceIterator f; std::vector vf; f = m.face.begin(); f += indice; for(; f != m.face.end();++f) { if(!f->IsD()) { f->SetS(); } } std::vector FPP; std::vector added; std::vector::iterator vfit; int i=1; printf("\n"); for(f = m.face.begin();f!=m.face.end();++f) if(!(*f).IsD()) { if( f->IsS() ) { f->V(0)->IsW(); f->V(1)->IsW(); f->V(2)->IsW(); } else { f->V(0)->ClearW(); f->V(1)->ClearW(); f->V(2)->ClearW(); } } BaseParameterClass pp; vcg::LocalOptimization Fs(m,&pp); Fs.SetTargetMetric(0.0f); Fs.Init(); Fs.DoOptimization(); do { vf.clear(); f = m.face.begin(); f += indice; for(; f != m.face.end();++f) { if(f->IsS()) { bool test= true; for(int ind =0;ind<3;++ind) f->V(ind)->InitIMark(); test = (DoubleArea(*f)/2) > AVG; if(test) { vf.push_back(&(*f)); } } } //info print printf("\r Refining [%d] - > %d",i,int(vf.size())); i++; FPP.clear(); added.clear(); for(vfit = vf.begin(); vfit!=vf.end();++vfit) { FPP.push_back(&(*vfit)); } int toadd= vf.size(); MyMesh::FaceIterator f1,f2; f2 = tri::Allocator::AddFaces(m,(toadd*2),FPP); MyMesh::VertexIterator vertp = tri::Allocator::AddVertices(m,toadd); std::vector added; added.reserve(toadd); vfit=vf.begin(); for(int i = 0; i >(vf[i],&(*f1),&(*f2),&(*vertp),CenterPoint() ); f1->SetS(); f2->SetS(); for(int itr=0;itr<3;itr++) { f1->V(itr)->SetW(); f2->V(itr)->SetW(); } added.push_back( &(*f1) ); added.push_back( &(*f2) ); } BaseParameterClass pp; vcg::LocalOptimization FlippingSession(m,&pp); FlippingSession.SetTargetMetric(0.0f); FlippingSession.Init(); FlippingSession.DoOptimization(); }while(!vf.empty()); vcg::LocalOptimization Fiss(m,&pp); Fiss.SetTargetMetric(0.0f); Fiss.Init(); Fiss.DoOptimization(); /*end refining */ tri::io::ExporterPLY::Save(m,"PreSmooth.ply",false); int UBIT = MyMesh::VertexType::LastBitFlag(); f = m.face.begin(); f += indice; for(; f != m.face.end();++f) { if(f->IsS()) { for(int ind =0;ind<3;++ind){ if(NormalTest(face::Pos(&(*f),ind ))) { f->V(ind)->SetUserBit(UBIT); } } f->ClearS(); } } for(vi=m.vert.begin();vi!=m.vert.end();++vi) if(!(*vi).IsD()) { if( vi->IsUserBit(UBIT) ) { (*vi).SetS(); vi->ClearUserBit(UBIT); } } tri::Smooth::VertexCoordLaplacian(m,1,true); printf("\nCompleted. Saving....\n"); tri::io::ExporterPLY::Save(m,argv[4],false); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_hole/trimesh_hole.pro0000644000175000017500000000063111551320477024443 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### TARGET = trimesh_hole DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_hole.cpp ../../../wrap/ply/plylib.cpp HEADERS += ../../../wrap/ply/plylib.h meshlab-1.3.2+dfsg1/vcglib/apps/sample/space_minimal/0000755000175000017500000000000012227522351021352 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/space_minimal/space_minimal.cpp0000644000175000017500000000217011517500567024665 0ustar gladkgladk#include #include #include #include #include using namespace vcg; // The shortest, simplest, dulliest introduction to the VCG Library int main(int argc, char *argv[]) { printf("Hello Library!\n"); // classical point types. // Point3f is just a typedef for Point3 Point3f pp0(0,1,2); Point3f pp1(2,1,0); // classical overloading of math operators Point3f pp2=pp1+pp0; //you can access to the components of a point with three different access methods // [0] [1] [2] <-- Preferred style // .X() .Y() .Z() // .V(0) .V(1) .V(2) printf("pp2: %f %f %f \n",pp2[0], pp2.Y(),pp2.V(2)); // Warning no implicit casts between different types // Conversions are explicit Point3i ppi=Point3i::Construct(pp1+pp0); Point4i size(0,0,1,1); // Colors are specialized Point4 // with a specialized constructor Color4b cb(Color4b::LightBlue); Color4f cf(Color4f::LightBlue); Color4b cbi; cbi.Import(cf); printf("ci %i %i %i %i\n",cbi.V(0),cbi.V(1),cbi.V(2),cbi.V(3)); return -1; }meshlab-1.3.2+dfsg1/vcglib/apps/sample/space_minimal/space_minimal.pro0000644000175000017500000000054211517500567024704 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### TARGET = trimesh_base LIBPATH += DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_base.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_join/0000755000175000017500000000000012227522351021243 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_join/trimesh_join.pro0000644000175000017500000000064511551320477024470 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### TARGET = trimesh_join DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app HEADERS += ../../../vcg/complex/trimesh/subset.h SOURCES += trimesh_join.cpp ../../../wrap/ply/plylib.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_join/trimesh_join.cpp0000644000175000017500000000663411551320477024456 0ustar gladkgladk#include #include #include #include #include #include #include #include #include #include // input output #include #include // std #include using namespace vcg; using namespace std; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsFaceType>{}; class MyVertex : public Vertex {}; class MyFace : public Face < MyUsedTypes, face::VertexRef, face::BitFlags > {}; class MyMesh : public vcg::tri::TriMesh< vector, vector > {}; int main(int argc,char **argv ) { if(argc<2) { printf( "\n trimesh_join ("__DATE__")\n" "Visual Computing Group I.S.T.I. C.N.R.\n" "Usage: trimesh_join [opt] filename.ply [filename.ply | *] \n" "where opt can be:\n" " -b xmin ymin zmin xmax ymax zmax : \n" " Returns only mesh composed by faces inside specified bbox\n" " -t Just scan all the input files computing the total bbox\n" ); exit(0); } MyMesh ml,mr; Box3f ClipBB,TotBB; bool ClipFlag=false,MergeFlag=true; int i=1; // Parsing option loop while(argv[i][0]=='-') { switch(argv[i][1]) { case 'b': { if(argc::Open(mr,argv[i])!=0) { printf("Error reading file %s\n",argv[1]); exit(0); } printf("Input mesh %3i vn:%9i fn:%9i\n",i, mr.vn, mr.fn); if(ClipFlag) { tri::GenericVertexInterpolator interp(mr); tri::TriMeshClipper::Box(ClipBB,interp,mr); printf(" clipped to vn:%9i fn:%9i\n", mr.vn, mr.fn); } tri::UpdateBounding::Box(mr); TotBB.Add(mr.bbox); if(MergeFlag) tri::Append::Mesh(ml,mr); // append mesh mr to ml ++i; } printf("Output mesh vn:%i fn:%i\n",ml.vn,ml.fn); tri::io::ExporterPLY::Save(ml,"joined.ply"); int dv=tri::Clean::RemoveDuplicateVertex(ml); printf("Removed %i duplicated vertices\n",dv); tri::io::ExporterPLY::Save(ml,"joined_unif.ply"); printf("Final BBox of mesh :\n (%7.4f %7.4f %7.4f) - (%7.4f %7.4f %7.4f)\n", TotBB.min[0],TotBB.min[1],TotBB.min[2], TotBB.max[0],TotBB.max[1],TotBB.max[2]); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_clustering/0000755000175000017500000000000012227522351022463 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_clustering/trimesh_clustering.cpp0000644000175000017500000000645411551320500027101 0ustar gladkgladk // mesh definition //#include //#include //#include #include #include #include #include #include #include #include #include #include // input output #include #include // std #include #include using namespace vcg; using namespace std; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::Normal3f, vertex::BitFlags >{}; class MyFace : public Face < MyUsedTypes, face::VertexRef, face::Normal3f, face::BitFlags > {}; class MyMesh : public vcg::tri::TriMesh< vector, vector > {}; int main(int argc, char **argv) { if(argc<3) { printf( "\n trimesh_clustering ("__DATE__")\n" " Visual Computing Group I.S.T.I. C.N.R.\n" "Usage: PlyRefine filein.ply fileout.ply [opt] \n" "options: \n" "-k cellnum approx number of cluster that should be defined; (default 10e5)\n" "-s size in absolute units the size of the clustering cell (override the previous param)\n" "-d enable the duplication of faces for double surfaces\n" ); exit(0); } int i=3; int CellNum=100000; float CellSize=0; bool DupFace=false; while(i::Open(m,argv[1])!=0) { printf("Error reading file %s\n",argv[1]); exit(0); } vcg::tri::UpdateBounding::Box(m); vcg::tri::UpdateNormals::PerFace(m); printf("Input mesh vn:%i fn:%i\n",m.vn,m.fn); vcg::tri::Clustering > Grid; Grid.DuplicateFaceParam=DupFace; Grid.Init(m.bbox,CellNum,CellSize); printf("Clustering to %i cells\n",Grid.Grid.siz[0]*Grid.Grid.siz[1]*Grid.Grid.siz[2] ); printf("Grid of %i x %i x %i cells\n",Grid.Grid.siz[0],Grid.Grid.siz[1],Grid.Grid.siz[2]); printf("with cells size of %.2f x %.2f x %.2f units\n",Grid.Grid.voxel[0],Grid.Grid.voxel[1],Grid.Grid.voxel[2]); int t0=clock(); Grid.AddMesh(m); int t1=clock(); Grid.ExtractMesh(m); int t2=clock(); printf("Output mesh vn:%i fn:%i\n",m.vn,m.fn); printf("Simplified in :%i msec (%i+%i)\n",t2-t0,t1-t0,t2-t1); vcg::tri::io::PlyInfo pi; vcg::tri::io::ExporterPLY::Save(m,argv[2],pi.mask); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_clustering/trimesh_clustering.pro0000644000175000017500000000076111551320500027112 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### # To solve issue related to slash vs. backslash under cygwin try: # env MINGW_IN_SHELL=1 qmake -spec win32-g++ TARGET = trimesh_clustering DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_clustering.cpp ../../../wrap/ply/plylib.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_closest/0000755000175000017500000000000012227522351021760 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_closest/trimesh_closest.cpp0000644000175000017500000001760612005675121025703 0ustar gladkgladk // stuff to define the mesh #include #include #include #include #include #include #include #include #include // io #include #include #include #include #include #include class BaseVertex; class BaseEdge; class BaseFace; struct BaseUsedTypes: public vcg::UsedTypes::AsVertexType,vcg::Use::AsEdgeType,vcg::Use::AsFaceType>{}; class BaseVertex : public vcg::Vertex< BaseUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags > {}; class BaseEdge : public vcg::Edge< BaseUsedTypes> {}; class BaseFace : public vcg::Face< BaseUsedTypes, vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::BitFlags, vcg::face::Mark, vcg::face::EdgePlaneEmpty > {}; class BaseMesh : public vcg::tri::TriMesh, std::vector > {}; class RTVertex; class RTEdge; class RTFace; struct RTUsedTypes: public vcg::UsedTypes::AsVertexType,vcg::Use::AsEdgeType,vcg::Use::AsFaceType>{}; class RTVertex : public vcg::Vertex< RTUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags > {}; class RTEdge : public vcg::Edge< RTUsedTypes> {}; class RTFace : public vcg::Face< RTUsedTypes, vcg::face::Normal3f, vcg::face::VertexRef, vcg::face::EdgePlane, vcg::face::Mark, vcg::face::BitFlags > {}; class RTMesh : public vcg::tri::TriMesh, std::vector > {}; using namespace vcg; void Usage() { printf( "\nUsage: trimesh_closest mesh.ply samplenum sampledistance(as fraction of bboxdiag)"); exit(-1); } // Testing of closest point on a mesh functionalities // Two main options // - using or not precomputed edges and planes // - using the simple wrapper or the basic functions of the grid. // - using the fn as size of the grid or the edge lenght as cell side template bool UnitTest_Closest(const char *filename1, int sampleNum, float dispPerc, std::vector resultVec) { MeshType mr; typedef typename MeshType::ScalarType ScalarType; typedef typename MeshType::CoordType CoordType; typedef typename MeshType::FaceType FaceType; typedef GridStaticPtr TriMeshGrid; int startOpen=clock(); int err=vcg::tri::io::Importer::Open(mr,filename1); tri::UpdateBounding::Box(mr); // tri::UpdateNormals::PerFaceNormalized(mr); tri::UpdateNormals::PerFace(mr); float dispAbs = mr.bbox.Diag()*dispPerc; if(err) { std::cerr << "Unable to open mesh " << filename1 << " : " << vcg::tri::io::Importer::ErrorMsg(err) << std::endl; exit(-1); } int endOpen = clock(); printf("Loading %6.3f - ",float(endOpen-startOpen)/CLOCKS_PER_SEC); int startSampling = clock(); std::vector MontecarloSamples; // First step build the sampling typedef tri::TrivialSampler BaseSampler; BaseSampler mcSampler(MontecarloSamples); tri::SurfaceSampling::SamplingRandomGenerator().initialize(123); tri::SurfaceSampling::Montecarlo(mr, mcSampler, sampleNum); math::MarsenneTwisterRNG rnd; rnd.initialize(123); for(size_t i=0;i::ComputeFaceEdgeAverage(mr); TRGrid.SetWithRadius(mr.face.begin(),mr.face.end(),avgEdge*2); } if(useEdge) tri::UpdateEdges::Set(mr); int endGridInit = clock(); printf("Grid Init %6.3f - ",float(endGridInit-startGridInit)/CLOCKS_PER_SEC); const ScalarType maxDist=std::max(dispAbs*10.0f,mr.bbox.Diag()/1000.f); CoordType closest; ScalarType dist; int startGridQuery = clock(); double avgDist=0; resultVec.resize(MontecarloSamples.size()); if(useEdge && useWrap) for(size_t i=0;i MarkerFace; MarkerFace mf; mf.SetMesh(&mr); face::PointDistanceBaseFunctor PDistFunct; for(size_t i=0;i MarkerFace; MarkerFace mf; mf.SetMesh(&mr); face::PointDistanceBaseFunctor PDistFunct; for(size_t i=0;i resultVecRT11; std::vector resultVecRT01; std::vector resultVecRT00; std::vector resultVecRT10; std::vector resultVecBS01; std::vector resultVecBS00; UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecRT11); UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecRT11); UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecRT01); UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecRT00); UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecRT10); UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecRT10); UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecRT10); UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecRT10); UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecBS01); UnitTest_Closest (argv[1],sampleNum,dispPerc,resultVecBS01); UnitTest_Closest(argv[1],sampleNum,dispPerc,resultVecBS01); UnitTest_Closest(argv[1],sampleNum,dispPerc,resultVecBS01); for(size_t i=0;i using namespace std; // VCG headers for triangular mesh processing #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include //#include //#include // VCG File Format Importer/Exporter #include #include #include // VCG Vertex // VCG Faces using namespace vcg; class MyFace; class MyEdge; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsEdgeType, Use ::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags, vertex::Normal3f, vertex::Mark>{}; class MyEdge : public Edge< MyUsedTypes, edge::VertexRef, edge::EVAdj> {}; class MyFace : public Face {}; class MyEdgeMesh: public tri::TriMesh< vector, vector > {}; class MyMesh : public tri::TriMesh< vector, vector >{}; typedef vcg::GridStaticPtr TriMeshGrid; int main(int argc,char ** argv) { if (argc<6) { printf("\n"); printf(" Usage: trimesh_intersection \n\n"); printf(" Mesh model to intersect (PLY format).\n"); printf(" The coefficients that specifying a plane in the form:\n\n"); printf(" a*x + b*y + c*z + d = 0\n\n\n"); printf(" Example: trimesh_intersection bunny.ply 0.0 1.0 0.0 0.0\n\n"); return 0; } MyMesh m; // open a mesh int err = tri::io::Importer::Open(m,argv[1]); if(err) { printf("Error in reading %s: '%s'\n",argv[1],tri::io::Importer::ErrorMsg(err)); exit(-1); } // some cleaning to get rid of bad file formats like stl that duplicate vertexes.. int dup = tri::Clean::RemoveDuplicateVertex(m); int unref = tri::Clean::RemoveUnreferencedVertex(m); if (dup > 0 || unref > 0) printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,argv[1]); // Compute cross-intersection with the given plane ///////////////////////////////////////////////////////// MyMesh::ScalarType a = static_cast(atof(argv[2])); MyMesh::ScalarType b = static_cast(atof(argv[3])); MyMesh::ScalarType c = static_cast(atof(argv[4])); MyMesh::ScalarType d = static_cast(atof(argv[5])); vcg::Point3 direction(a, b, c); MyMesh::ScalarType distance = -d / direction.Norm(); direction.Normalize(); vcg::Plane3 plane(distance, direction); MyEdgeMesh edge_mesh; // returned EdgeMesh (i.e. the cross-section) vcg::IntersectionPlaneMesh(m, plane, edge_mesh); // Compute bounding box vcg::tri::UpdateBounding::Box(edge_mesh); // export the cross-section tri::io::SVGProperties pro; if (tri::io::ExporterSVG::Save(edge_mesh, "out.svg",pro)) printf(" The cross-intersection has been successfully saved (OUT.SVG).\n"); else printf(" The cross-intersection cannot be saved.\n"); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ant_qt/0000755000175000017500000000000012227522351021572 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ant_qt/trimesh_ant_qt.pro0000644000175000017500000000201511761424114025333 0ustar gladkgladkVCGLIBDIR = ../../../../vcglib GLEWDIR = ../../../../code/lib/glew/ ANTDIR = ../../../../code/lib/AntTweakBar1.14/ HEADERS = glwidget.h SOURCES = glwidget.cpp \ main.cpp QT += opengl # Compile glew DEFINES += GLEW_STATIC INCLUDEPATH += $$GLEWDIR/include SOURCES += $$GLEWDIR/src/glew.c INCLUDEPATH += $$VCGLIBDIR INCLUDEPATH += $$GLEWDIR/include INCLUDEPATH += $$ANTDIR/include SOURCES += $$VCGLIBDIR/wrap/ply/plylib.cpp SOURCES += $$VCGLIBDIR/wrap/gui/trackball.cpp SOURCES += $$VCGLIBDIR/wrap/gui/trackmode.cpp SOURCES += $$VCGLIBDIR/wrap/qt/anttweakbarMapper.cpp # Awful problem with windows.. win32{ DEFINES += NOMINMAX LIBS +=$$ANTDIR/lib/AntTweakBar.lib } mac{ # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle LIBS +=$$ANTDIR/lib/libAntTweakBar.dylib QMAKE_POST_LINK ="cp -P ../../../../code/lib/AntTweakBar1.14/lib/libAntTweakBar.dylib . ; install_name_tool -change ../lib/libAntTweakBar.dylib ./libAntTweakBar.dylib $$TARGET" } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ant_qt/glwidget.h0000644000175000017500000000733311732414757023571 0ustar gladkgladk/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef GLWIDGET_H #define GLWIDGET_H #include /// vcg imports #include #include #include #include #include #include /// wrapper imports #include #include #include /// declaring edge and face type #include using namespace vcg; class CFace; class CVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsFaceType>{}; /// compositing wanted proprieties class CVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags>{}; class CFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags > {}; class CMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; class GLWidget : public QGLWidget { Q_OBJECT public: GLWidget(QWidget *parent = 0); bool hasToPick; Point2i pointToPick; ~GLWidget() {}; QSize sizeHint() const { return QSize(800, 600); }; protected: void initializeGL(); void paintGL(); void resizeGL(int width, int height); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseDoubleClickEvent ( QMouseEvent * event ); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); void wheelEvent(QWheelEvent *event); }; #endif meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ant_qt/glwidget.cpp0000644000175000017500000001653511732414757024130 0ustar gladkgladk/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include "glwidget.h" #include #include #include enum DrawMode{SMOOTH=vcg::GLW::DMSmooth, POINTS=vcg::GLW::DMPoints , WIRE, FLATWIRE,HIDDEN,FLAT}; TwBar *bar; char * filename;/// filename of the mesh to load CMesh mesh; /// the active mesh instance vcg::GlTrimesh glWrap; /// the active mesh opengl wrapper vcg::Trackball track; /// the active manipulator GLW::DrawMode drawmode=GLW::DMFlatWire; /// the current drawmode void TW_CALL loadTetrahedron(void *){ vcg::tri::Tetrahedron(mesh); vcg::tri::UpdateBounding::Box(mesh); vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(mesh); vcg::tri::UpdateNormals::PerFaceNormalized(mesh); glWrap.m = &mesh; glWrap.Update(); } void TW_CALL loadMesh(void *) { if(filename==0) return; int err=vcg::tri::io::ImporterPLY::Open(mesh,(char*)filename); if(err==ply::E_NOERROR) { vcg::tri::UpdateBounding::Box(mesh); vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(mesh); vcg::tri::UpdateNormals::PerFaceNormalized(mesh); glWrap.m = &mesh; glWrap.Update(); } } GLWidget::GLWidget(QWidget *parent) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) { filename=0; hasToPick=false; setWindowTitle(tr("Hello GL")); bar = TwNewBar("TweakBar"); TwCopyCDStringToClientFunc (CopyCDStringToClient); TwAddVarRW(bar,"Input",TW_TYPE_CDSTRING, &filename," label='Filepath' group=SetMesh help=` Name of the file to load` "); TwAddButton(bar,"Load from file",loadMesh,0, " label='Load Mesh' group=SetMesh help=`load the mesh` "); TwAddButton(bar,"Use tetrahedron",loadTetrahedron,0, " label='Make Tetrahedron' group=SetMesh help=`use tetrahedron.` "); // ShapeEV associates Shape enum values with labels that will be displayed instead of enum values TwEnumVal drawmodes[6] = { {GLW::DMSmooth, "Smooth"}, {GLW::DMPoints, "Per Points"}, {GLW::DMWire, "Wire"}, {GLW::DMFlatWire, "FlatWire"},{GLW::DMHidden, "Hidden"},{GLW::DMFlat, "Flat"}}; // Create a type for the enum shapeEV TwType drawMode = TwDefineEnum("DrawMode", drawmodes, 6); // add 'g_CurrentShape' to 'bar': this is a variable of type ShapeType. Its key shortcuts are [<] and [>]. TwAddVarRW(bar, "Draw Mode", drawMode, &drawmode, " keyIncr='<' keyDecr='>' help='Change draw mode.' "); } void GLWidget::initializeGL () { glClearColor(0, 0, 0, 0); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); } void GLWidget::resizeGL (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); TwWindowSize(w, h); initializeGL(); } void GLWidget::paintGL () { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40, GLWidget::width()/(float)GLWidget::height(), 0.1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,3.5f, 0,0,0, 0,1,0); track.center=vcg::Point3f(0, 0, 0); track.radius= 1; track.GetView(); glPushMatrix(); track.Apply(false); glPushMatrix(); if(mesh.vert.size()>0) { vcg::glScale(2.0f/mesh.bbox.Diag()); glTranslate(-mesh.bbox.Center()); glWrap.Draw(GLW::DrawMode(drawmode),GLW::CMNone,GLW::TMNone); } glPopMatrix(); track.DrawPostApply(); glPopMatrix(); if(hasToPick) { hasToPick=false; Point3f pp; if(Pick(pointToPick[0],pointToPick[1],pp)) { track.Translate(-pp); track.Scale(1.25f); QCursor::setPos(mapToGlobal(QPoint(width()/2+2,height()/2+2))); } } TwDraw(); } void GLWidget::keyReleaseEvent (QKeyEvent * e) { e->ignore (); if (e->key () == Qt::Key_Control) track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ControlModifier)); if (e->key () == Qt::Key_Shift) track.ButtonUp (QT2VCG (Qt::NoButton, Qt::ShiftModifier)); if (e->key () == Qt::Key_Alt) track.ButtonUp (QT2VCG (Qt::NoButton, Qt::AltModifier)); updateGL (); } void GLWidget::keyPressEvent (QKeyEvent * e) { e->ignore (); if (e->key () == Qt::Key_Control) track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ControlModifier)); if (e->key () == Qt::Key_Shift) track.ButtonDown (QT2VCG (Qt::NoButton, Qt::ShiftModifier)); if (e->key () == Qt::Key_Alt) track.ButtonDown (QT2VCG (Qt::NoButton, Qt::AltModifier)); TwKeyPressQt(e); updateGL (); } void GLWidget::mousePressEvent (QMouseEvent * e) { if(!TwMousePressQt(e)) { e->accept (); setFocus (); track.MouseDown (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ())); } updateGL (); } void GLWidget::mouseMoveEvent (QMouseEvent * e) { if (e->buttons ()) { track.MouseMove (e->x (), height () - e->y ()); updateGL (); } TwMouseMotion(e->x (), e->y ()); } void GLWidget::mouseDoubleClickEvent (QMouseEvent * e) { hasToPick=true; pointToPick=Point2i(e->x(),height()-e->y()); updateGL (); } void GLWidget::mouseReleaseEvent (QMouseEvent * e) { track.MouseUp (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ())); TwMouseReleaseQt(e); updateGL (); } void GLWidget::wheelEvent (QWheelEvent * e) { const int WHEEL_STEP = 120; track.MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ())); updateGL (); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ant_qt/main.cpp0000644000175000017500000000454111732414757023240 0ustar gladkgladk/**************************************************************************** ** ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor ** the names of its contributors may be used to endorse or promote ** products derived from this software without specific prior written ** permission. ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include "glwidget.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); if( !TwInit(TW_OPENGL, NULL) ) { fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError()); return 1; } GLWidget window; window.show(); return app.exec(); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/0000755000175000017500000000000012227522351022111 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/mesh_type.h0000644000175000017500000000653511551320477024274 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.1 2006/12/10 19:55:09 ganovelli first draft. Working but ugly interface. right mouse of the button to place a pos, then prss buttons. */ #pragma once /** the definition of vertex */ #include /** the definition of face */ #include /** definition of triangle mesh */ #include /** allocation vertices and faces of triangle mesh */ #include class DummyEdge; class StraightFace; /**************************************************************************************************************************/ /* DEFINITION OF A VERY STRAIGHT MESH. No optional atributes, just normals in the vertices and flags in vertices and faces*/ /** definition of a very simple vertex type. Just coordinates and normal as attributes*/ class StraightVertex: public vcg::VertexSimp2< StraightVertex, DummyEdge, StraightFace, vcg::vert::Coord3f,vcg::vert::VFAdj,vcg::vert::Normal3f,vcg::vert::BitFlags>{}; /** definition of a very simple face type. Just color and reference to vertices as attribute*/ class StraightFace: public vcg::FaceSimp2< StraightVertex, DummyEdge, StraightFace, vcg:: face::VertexRef, vcg:: face::FFAdj, vcg:: face::VFAdj,vcg:: face::Normal3f,vcg::face::BitFlags > {}; /** definition of a very simple mesh*/ class MyStraightMesh: public vcg::tri::TriMesh< std::vector,std::vector >{}; /****************************************************************************************************************************/ meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/window.cpp0000644000175000017500000000616611517500567024143 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.2 2006/12/10 22:17:18 ganovelli cvs problem during frist committ. repeated */ #include #include "glwidget.h" #include "window.h" #include "mesh_type.h" Window::Window() { glWidget = new GLWidget; fvButton = createButton("FlipV()",SLOT(flipV( ))); feButton = createButton("FlipE()",SLOT(flipE( ))); ffButton = createButton("FlipF()",SLOT(flipF( ))); neButton = createButton("NextE() {FlipE() + FlipF() }",SLOT(nextE( ))); nbButton = createButton("NextB() ",SLOT(nextB( ))); ldButton = createButton("Load TriMesh",SLOT(OpenFile( ))); vfButton = createButton("++()",SLOT(nextVfite())); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(glWidget); mainLayout->addWidget(fvButton); mainLayout->addWidget(feButton); mainLayout->addWidget(ffButton); mainLayout->addWidget(neButton); mainLayout->addWidget(nbButton); mainLayout->addWidget(vfButton); mainLayout->addWidget(ldButton); setLayout(mainLayout); glWidget->glWrap.m = &glWidget->mesh; setWindowTitle(tr("TriMesh Pos Demo")); } QPushButton *Window::createButton(const char *text, const char *setterSlot) { QPushButton *button = new QPushButton( text,0); button-> resize ( 50, 20 ); if(!connect(button, SIGNAL(clicked()), glWidget, setterSlot)) exit(0); return button; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/glwidget.h0000644000175000017500000000732311517500567024103 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.4 2007/05/17 09:06:44 ganovelli gestione double click Revision 1.3 2006/12/10 23:29:57 ganovelli added VFIterator (Pos is disabled in this version) Revision 1.2 2006/12/10 22:17:18 ganovelli cvs problem during frist committ. repeated */ #ifndef GLWIDGET_H_POS_DEMO #define GLWIDGET_H_POS_DEMO #include #include #include "mesh_type.h" #include #include #include #include class GLWidget : public QGLWidget { Q_OBJECT public: GLWidget(QWidget *parent = 0); ~GLWidget(); QSize minimumSizeHint() const; QSize sizeHint() const; int xRotation() const { return xRot; } MyStraightMesh mesh; vcg::GlTrimesh glWrap; vcg::Trackball track; int ScreenH,ScreenW,pic_x,pic_y,keypress; bool doPickPos,doPickVfIte; vcg::face::Pos< MyStraightMesh::FaceType> pos; vcg::face::VFIterator< MyStraightMesh::FaceType> vfite; public slots: void flipV( ); void flipE( ); void flipF( ); void nextE( ); void nextB( ); void nextVfite( ); void LoadTriMesh(QString& namefile); void OpenFile(); protected: void initializeGL(); void paintGL(); void resizeGL(int width, int height); void mouseDoubleClickEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void wheelEvent ( QWheelEvent * e ); void keyPressEvent ( QKeyEvent * e ); private: GLuint makeObject(); void quad(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2, GLdouble x3, GLdouble y3, GLdouble x4, GLdouble y4); void extrude(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); void normalizeAngle(int *angle); GLuint object; int xRot; QPoint lastPos; QColor trolltechGreen; QColor trolltechPurple; }; #endif meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/trimesh_vfiter_demo.cpp0000644000175000017500000000207411551320477026662 0ustar gladkgladk#include #include #include #include #include #include #include #include #include class MyEdge; class MyFace; class MyVertex: public vcg::VertexSimp2{}; class MyFace: public vcg::FaceSimp2{}; class MyMesh: public vcg::tri::TriMesh< std::vector, std::vector > {}; void OneRingNeighborhoodVF( MyVertex * v) { vcg::face::VFIterator vfi(v); //initialize the iterator tohe first face for(;!vfi.End();++vfi) { MyFace* f = vfi.F(); // ...do something with face f } } int main() { MyMesh m; vcg::tri::Tetrahedron(m); vcg::tri::UpdateTopology::VertexFace(m); OneRingNeighborhoodVF(&(*m.vert.begin())); return 0; }meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/glwidget.cpp0000644000175000017500000001737311551320477024442 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.4 2007/05/17 09:06:44 ganovelli gestione double click Revision 1.3 2006/12/10 23:29:57 ganovelli added VFIterator (Pos is disabled in this version) Revision 1.2 2006/12/10 22:17:18 ganovelli cvs problem during frist committ. repeated */ #include #include #include #include #include "glwidget.h" #include #include #include #include #include #include #include GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent) { object = 0; trolltechGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0); trolltechPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0); track.SetPosition(vcg::Point3f(0.0,0.0,0.0)); track.SetIdentity(); track.radius = 0.4; pos.f=NULL; vfite.f = NULL; doPickVfIte = false; doPickPos = false; } GLWidget::~GLWidget() { makeCurrent(); glDeleteLists(object, 1); } QSize GLWidget::minimumSizeHint() const { return QSize(50, 50); } QSize GLWidget::sizeHint() const { return QSize(400, 400); } void GLWidget::LoadTriMesh(QString &namefile) { vcg::tri::io::ImporterPLY::Open(mesh,namefile.toAscii()); vcg::tri::UpdateBounding::Box(mesh); vcg::tri::UpdateNormals::PerFace(mesh); vcg::tri::UpdateNormals::PerVertex(mesh); vcg::tri::UpdateTopology::FaceFace(mesh); vcg::tri::UpdateTopology::VertexFace(mesh); pos.f=0; vfite.f=NULL; } void GLWidget::OpenFile(){ QStringList filters; QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"),".", filters.join("\n")); if (fileName.isEmpty()) return; else LoadTriMesh( fileName ); } void GLWidget::flipV( ){ if(pos.f) pos.FlipV(); repaint(); } void GLWidget::flipE( ){ if(pos.f) pos.FlipE(); repaint(); } void GLWidget::flipF( ){ if(pos.f) pos.FlipF(); repaint(); } void GLWidget::nextE( ){ if(pos.f) pos.NextE(); repaint(); } void GLWidget::nextB( ){ if(pos.f) pos.NextB(); repaint(); } void GLWidget::nextVfite( ){ if(vfite.F()) ++vfite; repaint(); } void GLWidget::initializeGL() { qglClearColor(trolltechPurple.dark()); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); } template void drawVertex(VertexType & v){ glPushAttrib(0xffffffff); glPointSize(2.0); glBegin(GL_POINTS); glVertex(v.P()); glEnd(); glPopAttrib(); } void GLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,2, 0,0,0, 0,1,0); track.GetView(); track.Apply(); glScalef(1/glWrap.m->bbox.Diag(),1/glWrap.m->bbox.Diag(),1/glWrap.m->bbox.Diag()); glTranslate(-glWrap.m->bbox.Center()); // to do some picking MyStraightMesh::FaceType* fp=NULL; MyStraightMesh::VertexType* vp=NULL; if(doPickPos) { std::vector res; int yes = vcg::Pick(pic_x,ScreenH-pic_y+1,mesh.face,res,vcg::glTriangle3,1,1); if(yes) {fp = res[0]; pos.Set(fp,0,fp->V(0)); } doPickPos=false; }else if(doPickVfIte) { std::vector res; int yes = vcg::Pick(pic_x,ScreenH-pic_y+1,mesh.vert,res,drawVertex,3,3); if(yes) {vp = res[0]; MyStraightMesh::FaceType* g = vp->VFp(); vfite=vcg::face::VFIterator(vp); } doPickVfIte = false; } glWrap.Draw (); if(pos.f!=NULL) { glPushAttrib(0xffffffff); glDisable(GL_LIGHTING); glColor3f(0.0,1.0,0.0); glDepthRange(0.0,0.999); vcg::GlPos >::Draw(pos); glPopAttrib(); } if(vfite.F()!=NULL) { glPushAttrib(0xffffffff); glDisable(GL_LIGHTING); glColor3f(0.0,1.0,0.0); glDepthRange(0.0,0.99); vcg::GlVfIterator >::Draw(vfite); glPopAttrib(); } } void GLWidget::mouseMoveEvent(QMouseEvent *e) { track.MouseMove(e->x(),ScreenH-e->y()+1); repaint(); //if (event->buttons() & Qt::LeftButton) { // setXRotation(xRot + 8 * dy); //} else if (event->buttons() & Qt::RightButton) { // setXRotation(xRot + 8 * dy); //} // lastPos = event->pos(); } void GLWidget::keyPressEvent ( QKeyEvent * e ) { if((keypress == Qt::Key_Control)&&(e->key()==Qt::Key_Control)) keypress = -1; else keypress = e->key(); } void GLWidget::mouseDoubleClickEvent(QMouseEvent *e){ if(e->button() == Qt::RightButton) doPickPos=true; } void GLWidget:: mousePressEvent(QMouseEvent *e) { if( (keypress==Qt::Key_Control) && (e->button() == Qt::LeftButton) ) track.MouseDown(e->x(),ScreenH-e->y()+1,vcg::Trackball::KEY_CTRL|vcg::Trackball::BUTTON_LEFT ); else if(e->button() == Qt::LeftButton ) track.MouseDown(e->x(),ScreenH-e->y()+1,vcg::Trackball::BUTTON_LEFT); else if(e->button() == Qt::RightButton) { doPickVfIte=true; pic_x = e->x(); pic_y = e->y(); } repaint(); } void GLWidget::mouseReleaseEvent ( QMouseEvent * e ){ if( (keypress==Qt::Key_Control) && (e->button() == Qt::LeftButton) ) track.MouseUp(e->x(),ScreenH-e->y()+1,vcg::Trackball::KEY_CTRL ); else if(e->button() == Qt::LeftButton ) track.MouseUp(e->x(),ScreenH-e->y()+1,vcg::Trackball::BUTTON_LEFT); repaint(); } void GLWidget::resizeGL(int w,int h){ ScreenW=w; ScreenH=h; glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45,ScreenW/(float)ScreenH,0.01,5); } void GLWidget::wheelEvent ( QWheelEvent * e ){ int v = e->delta()/(float) 120; track.MouseWheel(v); repaint(); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/window.h0000644000175000017500000000450011517500567023576 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.2 2006/12/10 22:17:18 ganovelli cvs problem during frist committ. repeated */ #ifndef WINDOW_H_POS_DEMO #define WINDOW_H_POS_DEMO #include #include class QSlider; class GLWidget; class Window : public QWidget { Q_OBJECT public: Window(); private: QPushButton *createButton(const char *changedSignal, const char *setterSlot); GLWidget *glWidget; QPushButton * fvButton,*feButton,*ffButton,*neButton,*ldButton,*nbButton,*vfButton; }; #endif meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/main.cpp0000644000175000017500000000025411517500567023550 0ustar gladkgladk #include #include "window.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); Window wdw; wdw.show(); return app.exec(); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/trimesh_pos_demo.pro0000644000175000017500000000106311517500567026201 0ustar gladkgladkINCLUDEPATH += . ../../.. ../../../../code/lib ../../../../code/lib/glew/include HEADERS = glwidget.h \ window.h \ mesh_type.h SOURCES = glwidget.cpp \ main.cpp \ window.cpp\ ../../../../code/lib/glew/src/glew.c \ ../../../wrap/ply/plylib.cpp\ ../../../wrap/gui/trackmode.cpp\ ../../../wrap/gui/trackball.cpp QT += opengl # install target.path = $$./debug sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS trimesh_pos_demo.pro sources.path = ./ INSTALLS += target sources meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_pos_demo/trimesh_pos_demo.cpp0000644000175000017500000000261711551320477026167 0ustar gladkgladk#include #include #include #include #include #include #include #include #include class MyEdge; class MyFace; class MyVertex: public vcg::VertexSimp2{}; class MyFace: public vcg::FaceSimp2{}; class MyMesh: public vcg::tri::TriMesh< std::vector, std::vector > {}; void OneRingNeighborhood( MyFace * f) { MyVertex * v = f->V(0); MyFace* start = f; vcg::face::Pos p(f,0,v);// constructor that takes face, edge and vertex do { p.FlipF(); p.FlipE(); }while(p.f!=start); } #include // include the definition of jumping pos void OneRingNeighborhoodJP( MyFace * f) { MyVertex * v = f->V(0); MyFace* start = f; vcg::face::JumpingPos p(f,0,v);// constructor that takes face, edge and vertex do { p.NextFE(); }while(p.f!=start); } int main() { MyMesh m; vcg::tri::Tetrahedron(m); vcg::tri::UpdateTopology::FaceFace(m); OneRingNeighborhood(&(*m.face.begin())); OneRingNeighborhoodJP(&(*m.face.begin())); return 0; }meshlab-1.3.2+dfsg1/vcglib/apps/sample/polygonmesh_quadsimpl/0000755000175000017500000000000012227522351023174 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/polygonmesh_quadsimpl/polygonmesh_quadsimpl.pro0000755000175000017500000000027011522737362030352 0ustar gladkgladkTARGET = polygonmesh_quadsimpl LIBPATH += DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += ../../../wrap/ply/plylib.cpp \ quadsimpl.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/polygonmesh_quadsimpl/quadsimpl.cpp0000644000175000017500000003257111573077430025715 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ #include #include #include /*include the base definition for the vertex */ #include /*include the base definition for the face */ #include /*include the base definition for the edge */ #include /*include the base definition for the trimesh*/ #include /*include the algorithms for updating: */ #include /* topology */ #include /* bounding box */ #include /* normal */ /*include the algorithms for mesh fixing */ #include /*include the importer from disk*/ #include #include /* include the support for polygon meshes (function to convert from/to trimesh)*/ #include /* include the support for polygon meshes (the component for the face )*/ #include /* include the support for half edges */ #include #include #include #include #include using namespace vcg; using namespace std; // forward declarations class CFace; class CVertex; class CHEdge; class CEdge; class MyPolyVertex; struct CUsedTypes: public vcg::UsedTypes< vcg::Use::AsVertexType, vcg::Use::AsFaceType >{}; // Mesh of triangles class CVertex : public Vertex< CUsedTypes, vertex::BitFlags, vertex::Coord3f, vertex::Normal3f, vertex::VFAdj, vertex::Mark, vcg::vertex::Curvaturef, vcg::vertex::CurvatureDirf, vertex::Color4b, vertex::Qualityf >{}; class CFace : public Face< CUsedTypes, face::VertexRef, face::Normal3f, face::BitFlags, face::FFAdj, face::VFAdj, face::Mark, face::EdgePlane > {}; class CMesh : public vcg::tri::TriMesh< vector, vector > {}; // Poly mesh class MyPolyFace; class MyPolyVertex; struct PolyUsedTypes: public vcg::UsedTypes< vcg::Use ::AsVertexType, vcg::Use ::AsEdgeType, vcg::Use ::AsHEdgeType, vcg::Use ::AsFaceType >{}; class MyPolyVertex:public Vertex< PolyUsedTypes, vertex::Coord3f, vertex::Normal3f, vertex::Mark, vertex::BitFlags, vertex::VHAdj, vertex::VFAdj >{}; class CEdge : public Edge{}; class CHEdge : public HEdge< PolyUsedTypes, hedge::BitFlags, hedge::HFAdj, hedge::HOppAdj, hedge::HNextAdj, hedge::HVAdj, hedge::HPrevAdj, hedge::Mark >{}; class MyPolyFace:public Face< PolyUsedTypes, face::PolyInfo, face::PFVAdj, face::PFFAdj, face::PFHAdj, face::BitFlags, face::Normal3f, face::Mark > {}; class MyPolyMesh: public tri::TriMesh< std::vector, std::vector, std::vector, std::vector >{}; /*! * \brief Collapse operation for adaptive simplification using fitmaps * */ class MyCollapseAdaptive: public vcg::tri::QuadDiagonalCollapse< MyPolyMesh, MyCollapseAdaptive, CMesh , vcg::tri::VertReg ,vcg::tri::FitmapsCollapse , vcg::tri::FitmapsCollapse > { public: typedef vcg::tri::QuadDiagonalCollapse< MyPolyMesh, MyCollapseAdaptive, CMesh , vcg::tri::VertReg, vcg::tri::FitmapsCollapse , vcg::tri::FitmapsCollapse > constructor; MyCollapseAdaptive(HEdgePointer he, int mark):constructor(he,mark){} }; /*! * \brief Collapse for uniform simplification * */ class MyCollapse: public vcg::tri::QuadDiagonalCollapseBase< MyPolyMesh, MyCollapse, CMesh , vcg::tri::VertReg > { public: typedef vcg::tri::QuadDiagonalCollapseBase< MyPolyMesh, MyCollapse, CMesh , vcg::tri::VertReg > constructor; MyCollapse(HEdgePointer he, int mark):constructor(he,mark){} }; typedef CMesh::FaceType TriFaceType; typedef vcg::GridStaticPtr GRID; typedef CMesh::PerVertexAttributeHandle Fitmap_attr; /*! Initializes the grid for smoothing and fitmaps * * \param m Reference mesh * */ void initGrid(CMesh & m) { GRID* grid = new GRID(); vcg::tri::UpdateBounding::Box(m); vcg::tri::UpdateEdges::Set(m); grid->Set(m.face.begin(), m.face.end()); // grid->ShowStats(stdout); MyCollapse::grid() = grid; MyCollapseAdaptive::grid() = grid; } /*! Initializes the heap of operations on a mesh * * \param m Mesh * \param loc * \param Adaptive Specifies if simplificaton will be adaptive * */ void init_heap(MyPolyMesh &m, vcg::LocalOptimization &loc, bool adaptive) { if(adaptive) MyCollapseAdaptive::Init(m, loc.h); else MyCollapse::Init(m,loc.h); std::make_heap(loc.h.begin(),loc.h.end()); if(!loc.h.empty()) loc.currMetric=loc.h.front().pri; } /*! Read fitmaps values from a file and loads them into a mesh * * \param m Mesh * \param fn Name of the file to read * */ bool read_fitmaps(CMesh &m, const char *fn) { ifstream fitmaps; fitmaps.open(fn); if(! fitmaps.is_open()) return false; Fitmap_attr S_Fit = tri::Allocator::GetPerVertexAttribute(m,"S-Fitmap"); Fitmap_attr M_Fit = tri::Allocator::GetPerVertexAttribute(m,"M-Fitmap"); int index; float S_fit, M_fit; do { fitmaps >> index >> S_fit >> M_fit; S_Fit[m.vert[index]] = S_fit; M_Fit[m.vert[index]] = M_fit; }while(fitmaps.good()); bool eof = fitmaps.eof(); fitmaps.close(); return eof; } /*! Writes fitmaps values into a file * * \param m Mesh * \param fn Name of the file to write * */ bool store_fitmaps(CMesh &m, const char *fn) { ofstream fitmaps; fitmaps.open(fn); if(! fitmaps.is_open()) return false; Fitmap_attr S_Fit = tri::Allocator::GetPerVertexAttribute(m,"S-Fitmap"); Fitmap_attr M_Fit = tri::Allocator::GetPerVertexAttribute(m,"M-Fitmap"); for(unsigned int i =0; i< m.vert.size(); i++) { if( !(m.vert[i].IsD()) ) { fitmaps << i << " " << S_Fit[m.vert[i]] << " " << M_Fit[m.vert[i]] << endl; if(!fitmaps.good()) { fitmaps.close(); return false; } } } fitmaps.close(); return true; } /*! Load fitmaps for a mesh, computing them or reading values from a file * * \param m Mesh * \param fn Name of the mesh file * */ void load_fitmaps(CMesh &m, char* fn) { Fitmap_attr S_Fit = tri::Allocator::AddPerVertexAttribute (m, string("S-Fitmap")); Fitmap_attr M_Fit = tri::Allocator::AddPerVertexAttribute (m, string("M-Fitmap")); string filename(fn); int found = filename.find_last_of("/"); string name = filename.substr(found+1); string suffix = ".fmp"; if( !read_fitmaps( m, (name + suffix).c_str()) ) { tri::Fitmaps::computeSFitmap(m); for(CMesh::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) S_Fit[vi] = vi->Q(); tri::Fitmaps::computeMFitmap(m, 5); for(CMesh::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) M_Fit[vi] = vi->Q(); store_fitmaps(m, ( name + suffix).c_str()); } } /*! Load a mesh, from a file * * \param m Mesh that will be filled with data from a file * \param fn Name of the mesh file * \param loadFitmaps Specifies if fitmaps have to be loaded * */ void loadMesh(CMesh & m, char* fn, bool loadFitmaps = false) { int ret = vcg::tri::io::Importer::Open(m,fn); if(ret != 0) { cerr << "Error reading file " << fn << endl; exit(1); } tri::Clean::RemoveDegenerateFace(m); tri::Clean::RemoveDuplicateFace(m); tri::Clean::RemoveDuplicateVertex(m); tri::Clean::RemoveUnreferencedVertex(m); tri::UpdateTopology::FaceFace(m); tri::Clean::RemoveNonManifoldFace(m); tri::UpdateTopology::FaceFace(m); tri::Clean::RemoveNonManifoldVertex(m); tri::UpdateTopology::FaceFace(m); // update bounding box vcg::tri::UpdateBounding::Box (m); // update Normals vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(m); vcg::tri::UpdateNormals::PerFaceNormalized(m); if(loadFitmaps) load_fitmaps(m,fn); } int main(int argc, char *argv[]) { // HE mesh MyPolyMesh pm; // Tri meshes CMesh mesh,refMesh; char* meshfile = NULL; char* trimeshfile = NULL; char* outfile = "output.off"; int faces; bool adaptive = false; if(argc < 2) { cerr << "Usage: " << argv[0] << " -meshfile filename [-trimeshfile filename] -faces num_faces [-adaptive] [-outfile filename]" << endl; } for(int i=1; i< argc; i++) { string arg = string(argv[i]); if ( arg == "-meshfile") meshfile = argv[++i]; else if (arg == "-trimeshfile") trimeshfile = argv[++i]; else if (arg == "-faces") { stringstream myStream(argv[++i], stringstream::in | stringstream::out); myStream >> faces; } else if (arg == "-outfile") outfile = argv[++i]; else if (arg == "-adaptive") adaptive = true; } if( !meshfile) { cerr << "Missing mesh filename" << endl; exit(1); } if(faces < 0) { cerr << "Missing faces number" << endl; exit(1); } // Load the mesh to simplify loadMesh(mesh, meshfile); // Load the reference mesh if(trimeshfile) loadMesh(refMesh, trimeshfile, adaptive); else loadMesh(refMesh, meshfile, adaptive); initGrid(refMesh); MyCollapse::refMesh() = &refMesh; MyCollapseAdaptive::refMesh() = &refMesh; vcg::tri::PolygonSupport::ImportFromTriMesh(pm,mesh); vcg::tri::UpdateHalfEdges::FromIndexed(pm); // After loading check mesh consistency assert(vcg::tri::UpdateHalfEdges::CheckConsistency(pm)); HalfedgeQuadClean::remove_singlets(pm); HalfedgeQuadClean::remove_doublets(pm); vcg::LocalOptimization loc(pm); init_heap(pm, loc, adaptive); loc.HeapSimplexRatio = 9; loc.SetTargetSimplices(faces); // Perform simplification loc.DoOptimization(); assert(vcg::tri::UpdateHalfEdges::CheckConsistency(pm)); vcg::tri::UpdateIndexed::FromHalfEdges(pm ); int ret = tri::io::ExporterOFF::Save(pm, outfile, tri::io::Mask::IOM_BITPOLYGONAL ); if(ret != 0 ) { cerr << "Error saving file" << endl; exit(1); } cout << "Simplification ended successfully!" << endl; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/polygonmesh_zonohedra/0000755000175000017500000000000012227522351023166 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/polygonmesh_zonohedra/polygonmesh_zonohedra.cpp0000644000175000017500000001023412005675121030305 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ #include #include #include #include #include #include #include #include #include class MyVertex; class MyEdge; class MyFace; struct MyUsedTypes: public vcg::UsedTypes::AsVertexType,vcg::Use::AsEdgeType,vcg::Use::AsFaceType>{}; class MyVertex : public vcg::Vertex< MyUsedTypes,vcg::vertex::Coord3f,vcg::vertex::BitFlags >{}; class MyEdge : public vcg::Edge< MyUsedTypes > {}; class MyFace : public vcg::Face< MyUsedTypes, vcg::face::FFAdj, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags > {}; // the main mesh class class MyMesh : public vcg::tri::TriMesh, std::vector > {}; // example 1: build a cube as a Zonohedron void example1(){ vcg::tri::Zonohedron z; z.addVector( 0,0,1 ); z.addVector( 0,1,0 ); z.addVector( 1,0,0 ); MyMesh m; z.createMesh(m); // this will be a cube vcg::tri::UpdateTopology::FaceFace(m); // needed by exporter int savemask = vcg::tri::io::Mask::IOM_BITPOLYGONAL; vcg::tri::io::ExporterOFF::Save(m,"cube.off",savemask); } // example2: reads input file, builds zonohedra as described there void example2(){ FILE* f = fopen("input.txt","rt"); if (!f) return; while (1) { // read mesh name char meshFilename[1024], fullMeshFilename[1024]; if (fscanf(f,"%s",meshFilename)!=1) break; sprintf(fullMeshFilename,"%s.off",meshFilename); // build input vector vcg::tri::Zonohedron z; while (1) { float a,b,c; if (fscanf(f,"%f %f %f",&a, &b, &c)!=3) break; z.addVector(a,b,c); } printf("Building %s from %d vectors...\n",fullMeshFilename, z.vectors().size() ); MyMesh m; z.createMesh(m); vcg::tri::UpdateTopology::FaceFace(m); // needed by exporter // normally, faces with more than 4sides are split into parallelograms // this merges them (optional, try removing it!) vcg::tri::PolygonSupport::MergeFlatFaces(m); int savemask = vcg::tri::io::Mask::IOM_BITPOLYGONAL; vcg::tri::io::ExporterOFF::Save(m,fullMeshFilename,savemask); } } int main(int argc, char *argv[]){ example1(); example2(); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/polygonmesh_zonohedra/input.txt0000644000175000017500000000045312005675121025066 0ustar gladkgladkcube 0 0 1 0 1 0 1 0 0 funny 0 0 4 0 4 0 4 0 0 0 1 1 1 1 0 1 0 1 0 1 -1 1 -1 0 -1 0 1 prism8 0 3 0 1 0 0 0 0 1 1 0 1 1 0 -1 prismCoolEnd 0 6 0 3 0 0 0 0 3 1 0 1 1 0 -1 1 1 1 -1 1 1 1 1 -1 -1 1 -1 strangeDie 0 0 3 0 3 0 3 0 0 1 -1 1 1 1 -1 1 -1 -1 1 1 1 meshlab-1.3.2+dfsg1/vcglib/apps/sample/sample.pro0000644000175000017500000000136211551320500020545 0ustar gladkgladk###################################################################### # Hand made pro. ###################################################################### TEMPLATE = subdirs SUBDIRS = trimesh_base \ trimesh_topology\ trimesh_smooth \ trimesh_refine \ trimesh_clustering \ trimesh_isosurface \ trimesh_join \ trimesh_optional \ trimesh_intersection \ trimesh_ball_pivoting \ trimesh_hole \ polygonmesh_base \ aabb_binary_tree \ trimesh_attribute sources.files = *.pro sources.path = . INSTALLS += sources meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ball_pivoting/0000755000175000017500000000000012227522351023135 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ball_pivoting/trimesh_ball_pivoting.cpp0000644000175000017500000000602711551320477030236 0ustar gladkgladk // mesh definition //#include //#include //#include #include #include #include #include #include #include #include #include #include // input output #include #include // std #include #include #include using namespace vcg; using namespace std; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::Normal3f, vertex::BitFlags, vertex::Mark>{}; class MyFace : public Face < MyUsedTypes, face::VertexRef, face::Normal3f, face::BitFlags > {}; class MyMesh : public vcg::tri::TriMesh< vector, vector > {}; bool callback(int percent, const char *str) { cout << "str: " << str << " " << percent << "%\n"; return true; } int main(int argc, char **argv) { if(argc<3) { printf( "\n trimesh_ball_pivoting ("__DATE__")\n" " Visual Computing Group I.S.T.I. C.N.R.\n" "Usage: trimesh_ball_pivoting filein.ply fileout.ply [opt]\n" "options: \n" "-r radius of the rolling ball\n" "-c clustering radius (as fraction of radius) default: 0.05\n" ); exit(0); } float radius = 0.0f; float clustering = 0.05; int i = 3; while(i::Open(m,argv[1])!=0) { printf("Error reading file %s\n",argv[1]); exit(0); } vcg::tri::UpdateBounding::Box(m); vcg::tri::UpdateNormals::PerFace(m); printf("Input mesh vn:%i fn:%i\n",m.vn,m.fn); int t0=clock(); // Initialization tri::BallPivoting pivot(m, radius, clustering); printf("Ball radius: %f\nClustering points withing %f radii\n", pivot.radius, clustering); int t1=clock(); // the main processing pivot.BuildMesh(callback); int t2=clock(); printf("Output mesh vn:%i fn:%i\n",m.vn,m.fn); printf("Created in :%i msec (%i+%i)\n",t2-t0,t1-t0,t2-t1); vcg::tri::io::PlyInfo pi; vcg::tri::io::ExporterPLY::Save(m,argv[2],pi.mask); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ball_pivoting/trimesh_ball_pivoting.pro0000644000175000017500000000076711551320477030261 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### # To solve issue related to slash vs. backslash under cygwin try: # env MINGW_IN_SHELL=1 qmake -spec win32-g++ TARGET = trimesh_ball_pivoting DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_ball_pivoting.cpp ../../../wrap/ply/plylib.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/hashing_2D/0000755000175000017500000000000012227522351020517 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/hashing_2D/test_hash2D.cpp0000644000175000017500000002246511772555544023422 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2009 \/)\/ * * 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. * * * ****************************************************************************/ #include #include #include #include #include #include typedef double MyScalarType; class MySegmentType:public vcg::Segment2 { public: int mark; bool deleted; bool IsD(){return deleted;} MySegmentType(const vcg::Point2 &_P0, const vcg::Point2 &_P1) { P0()=_P0; P1()=_P1; mark=0; } void GetBBox(vcg::Box2 &BB2) { //BB2.SetNull(); BB2.Set(P0()); BB2.Add(P1()); } MySegmentType(){} MySegmentType(const MySegmentType &s1) { P0()=s1.P0(); P1()=s1.P1(); mark=s1.mark; deleted=s1.deleted; } }; //**MARKER CLASSES**// class MyMarker { public: int mark; MyMarker(){mark=0;} //MyMarker( MESH_TYPE *m) {SetMesh(m);} void UnMarkAll(){mark++;} bool IsMarked(MySegmentType* obj) {return(obj->mark==mark);} void Mark(MySegmentType* obj) {obj->mark=mark;} /*void SetMesh(MESH_TYPE *_m) {m=_m;}*/ }; vcg::SpatialHashTable2D Hash2D; std::vector Allocated; MyMarker MyMark; void RandomSeg(vcg::Point2 &P0, vcg::Point2 &P1, MyScalarType SpaceSize=100, MyScalarType maxdim=0.01) { MyScalarType dimAbs=SpaceSize*maxdim; int dimension=RAND_MAX; int X=rand(); int Y=rand(); int dX=rand(); int dY=rand(); MyScalarType size=((MyScalarType)(rand()))/(MyScalarType)dimension; P0=vcg::Point2((MyScalarType)X/dimension,(MyScalarType)Y/dimension); P0*=SpaceSize; vcg::Point2 D=vcg::Point2((MyScalarType)dX/dimension,(MyScalarType)dY/dimension); D.Normalize(); D*=size*dimAbs; P1=P0+D; } void InitRandom(int num, MyScalarType SpaceSize=100, MyScalarType maxdim=0.01) { Allocated.clear(); Allocated.resize(num); srand(clock()); for (int i=0;i P0,P1; RandomSeg(P0,P1,SpaceSize,maxdim); Allocated[i]=MySegmentType(P0,P1); Allocated[i].deleted=false; } } MyScalarType TestBox(int num_test=100000, MyScalarType SpaceSize=100, MyScalarType maxdim=0.02) { //GetInBox(OBJMARKER & _marker,const Box2x _bbox,OBJPTRCONTAINER & _objectPtrs) MyMark.UnMarkAll(); int t0=clock(); int num=0; for (int i=0;i P0,P1; RandomSeg(P0,P1,SpaceSize,maxdim); vcg::Box2 bbox; bbox.Add(P0); bbox.Add(P1); std::vector result; num+=Hash2D.GetInBox >(MyMark,bbox,result); } int t1=clock(); MyScalarType numd=(double)num/(double)num_test; return numd; } //void TestCorrectNess(int num_sample=1000, // int num_test=1000, // MyScalarType SpaceSize=100, // MyScalarType radius=0.02) //{ // //} void GetIntersectingSegments(MySegmentType *S, std::vector &result) { ///get the bbox result.clear(); vcg::Box2 bbox; S->GetBBox(bbox); ///then get into the grid std::vector inbox; int num=Hash2D.GetInBox >(MyMark,bbox,inbox); ///then test intersection for (int j=0;j p_inters; if (vcg::SegmentSegmentIntersection(*S,*inbox[j],p_inters)) result.push_back(inbox[j]); } } void GetCloseSegments(MySegmentType *S, const MyScalarType &radius, std::vector &result) { ///get the bbox result.clear(); vcg::Box2 bbox; S->GetBBox(bbox); bbox.Offset(radius);//*1.02); ///then get into the grid std::vector inbox; int num=Hash2D.GetInBox >(MyMark,bbox,inbox); ///then test intersection for (int j=0;j p_clos; MyScalarType dist=vcg::Segment2DSegment2DDistance(*S,*inbox[j],p_clos); if (dist result; GetIntersectingSegments(&Allocated[i],result); num_inters+=result.size(); } return ((MyScalarType)num_inters/(MyScalarType)num_test); } MyScalarType TestClosest(int num_test=1000000, MyScalarType radius=0.1) { int num_found=0; for (int i=0;iLength()*radius; ///get the segments closer than a radius std::vector closer; GetCloseSegments(S,absRadius,closer); num_found+=closer.size(); } return ((MyScalarType)num_found/(MyScalarType)num_test); } int TestCorrectIntersect(int num_test=1000) { int num=0; for (int i=0;i result0,result1; for (int j=0;j p_inters; if (vcg::SegmentSegmentIntersection(S0,*S1,p_inters)) result0.push_back(S1); /*num+=result0.size();*/ } GetIntersectingSegments(&Allocated[i],result1); ///then see if equal number if (result1.size()==result0.size())num++; } return (num); } int TestCorrectClosest(int num_test=1000, MyScalarType radius=0.1) { int num=0; for (int i=0;i result0,result1; MyScalarType absRadius=S0->Length()*radius; for (int j=0;j p_clos; MyScalarType dist=vcg::Segment2DSegment2DDistance(*S0,*S1,p_clos); if (dist using namespace std; // VCG headers for triangular mesh processing #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // VCG File Format Importer/Exporter #include #include using namespace vcg; class MyFace; class MyEdge; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsEdgeType, Use ::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::BitFlags, vertex::Normal3f, vertex::Mark,vertex::Color4b, vertex::Qualityf>{}; class MyEdge : public Edge{}; class MyFace : public Face {}; class MyMesh : public tri::TriMesh< vector, vector >{}; // Uncomment only one of the two following lines to test different data structures typedef vcg::GridStaticPtr TriMeshGrid; //typedef vcg::SpatialHashTable TriMeshGrid; int main(int argc,char ** argv) { if (argc<2) { printf("\n"); printf(" Compute an approximation of the shape diameter function\n"); printf(" Usage: trimesh_intersection [angle samplenum]\n\n"); printf(" Mesh model for which to compute the sdf (PLY format).\n"); printf(" angle the wideness (degree) of the cone of ray that must be shot from each vertex (default 45)\n"); printf(" samplenum the oversampling factor (0 -> one ray, 1, 9 ray, 2-> 25 rays (default 2)\n"); return 0; } MyMesh m; int t0=clock(); // open a mesh int err = tri::io::Importer::Open(m,argv[1]); if(err) { printf("Error in reading %s: '%s'\n",argv[1],tri::io::Importer::ErrorMsg(err)); exit(-1); } // the other parameters float widenessRad = math::ToRad(20.0); if(argc>2) { widenessRad = math::ToRad(atof(argv[2])); printf("Setting wideness to %f degree\n",atof(argv[2])); } int n_samples=2; if(argc>3) n_samples = atoi(argv[3]); int samplePerVert = (n_samples*2+ 1)*(n_samples*2+ 1); printf("Using oversampling to %i (%i sample per vertex)\n",n_samples,samplePerVert); // some cleaning to get rid of bad stuff int dup = tri::Clean::RemoveDuplicateVertex(m); int unref = tri::Clean::RemoveUnreferencedVertex(m); if (dup > 0 || unref > 0) printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,argv[1]); // updating tri::UpdateBounding::Box(m); tri::UpdateNormals::PerFaceNormalized(m); tri::UpdateNormals::PerVertexAngleWeighted(m); tri::UpdateNormals::NormalizeVertex(m); // Create a static grid (for fast indexing) and fill it TriMeshGrid static_grid; static_grid.Set(m.face.begin(), m.face.end()); typedef MyMesh::ScalarType ScalarType; int t1=clock(); float t; MyMesh::FaceType *rf; MyMesh::VertexIterator vi; float maxDist=m.bbox.Diag(); float offset= maxDist / 10000.0; int totRay=0; ScalarType deltaRad=widenessRad/(ScalarType)(n_samples*2); if(n_samples==0) deltaRad=0; tri::UpdateQuality::VertexConstant(m,0); for(vi=m.vert.begin();vi!=m.vert.end();++vi) { vcg::Ray3f ray; ray.SetOrigin((*vi).cP()-((*vi).cN()*offset)); Point3f dir0 = -(*vi).cN(); int cnt=0; ScalarType theta_init,phi_init,ro; dir0.ToPolarRad(ro,theta_init,phi_init); for (int x=-n_samples;x<=n_samples;x++) for (int y=-n_samples;y<=n_samples;y++) { ScalarType theta=theta_init+x*deltaRad; ScalarType phi=phi_init+y*deltaRad; if (theta<0) theta=2.0*M_PI+theta; Point3f dir; dir.FromPolarRad(ro,theta,phi); dir.Normalize(); ray.SetDirection(dir); rf = tri::DoRay(m,static_grid,ray,maxDist,t); if(rf) { (*vi).Q()+=t; cnt++; } } if(cnt>0){ (*vi).Q()/=cnt; totRay+=cnt; } } int t2 = clock(); tri::UpdateColor::VertexQualityRamp(m); tri::io::ExporterPLY::Save(m,"SDF.ply",tri::io::Mask::IOM_VERTCOLOR+tri::io::Mask::IOM_VERTQUALITY); printf("Initializated in %i msec\n",t1-t0); printf("Completed in %i msec\n",t2-t1); printf("Shoot %i rays and found %i intersections\n",m.vn*samplePerVert,totRay); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/space_packer/0000755000175000017500000000000012227522351021171 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/space_packer/space_packer.pro0000644000175000017500000000077111761424114024340 0ustar gladkgladkQT += opengl svg TARGET = space_packer DEPENDPATH += . ../../.. INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += space_packer.cpp ../../../../vcglib/wrap/qt/PolyToQImage.cpp HEADERS += ../../../vcg/space/rect_packer.h \ ../../../vcg/math/similarity2.h \ ../../../vcg/space/poly_packer.h # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle # Awful problem with windows.. win32{ DEFINES += NOMINMAX } QT += opengl svgmeshlab-1.3.2+dfsg1/vcglib/apps/sample/space_packer/space_packer.cpp0000644000175000017500000001165211732414757024334 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2009 \/)\/ * * 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. * * * ****************************************************************************/ #include #include #include #include #include #include #include #include using namespace vcg; using namespace std; static void buildRandRectSet(int rectNum, vector &rectVec) { math::MarsenneTwisterRNG rnd; float exp=3.0f; float ratioMin=0.2; float ratioMax=0.9; float sizeMin=0.1; float sizeMax=1.0f; rnd.initialize(time(0)); for(int i=0;i &rectVec) { math::MarsenneTwisterRNG rnd; float exp=5.0f; rnd.initialize(time(0)); for(int i=0;i > &polyVec) { vcg::math::MarsenneTwisterRNG rnd; rnd.initialize(time(0)); for(int i=0;i poly; for(int j=0;j<10;j++) poly.push_back(Point2f(0.5+0.5*rnd.generate01(),2.0f*M_PI*rnd.generate01())); std::sort(poly.begin(),poly.end()); float ratio = rnd.generateRange(0.2,0.9); float rot = rnd.generateRange(-M_PI,M_PI); float scale = pow(rnd.generateRange(0.3,0.9),1); for(size_t j=0;j rectVec; buildRandRectSet(1000, rectVec); vector trVec; vector< vector > polySet; Point2f finalSize; buildRandPolySet(100,polySet); PolyDumperParam pp; /* PolyPacker::PackAsEqualSquares(polySet,Point2f(1024.0f,1024.0f),trVec,finalSize); dumpPolySet("testpolyEq.png",polySet,trVec,pp); PolyPacker::PackAsAxisAlignedRect(polySet,Point2f(1024.0f,1024.0f),trVec,finalSize); dumpPolySet("testpolyAA.png",polySet,trVec,pp); PolyPacker::PackAsObjectOrientedRect(polySet,Point2f(1024.0f,1024.0f),trVec,finalSize); dumpPolySet("testpolyOO.png",polySet,trVec,pp);*/ //PolyPacker::PackAsAxisAlignedRect(polySet,Point2f(1024.0f,1024.0f),trVec,finalSize); PolyPacker::PackAsObjectOrientedRect(polySet,Point2f(1024.0f,1024.0f),trVec,finalSize); //dumpPolySetPNG("testpolyEq.png",polySet,trVec,pp); PolyDumper::dumpPolySetSVG("testpolyEq.svg",polySet,trVec,pp); /*PolyPacker::PackAsAxisAlignedRect(polySet,Point2f(1024.0f,1024.0f),trVec,finalSize); dumpPolySetSVG("testpolyAA.svg",polySet,trVec,pp); PolyPacker::PackAsObjectOrientedRect(polySet,Point2f(1024.0f,1024.0f),trVec,finalSize); dumpPolySetSVG("testpolyOO.svg",polySet,trVec,pp);*/ return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_split_vertex/0000755000175000017500000000000012227522351023034 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_split_vertex/trimesh_split_vertex.pro0000644000175000017500000000027311517500567030051 0ustar gladkgladkTARGET = trimesh_split_vertex LIBPATH += DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += trimesh_split_vertex.cpp ../../../wrap/ply/plylib.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_split_vertex/trimesh_split_vertex.cpp0000644000175000017500000001251111551320477030027 0ustar gladkgladk#include #include #include #include #include #include #include #include #include /* this sample shows how to transfer per wedge attributes from wedges to vertices. during the process new vertices could be created. */ using namespace vcg; #define TEST_IN_PLACE_SPLIT #ifdef TEST_IN_PLACE_SPLIT class SrcVertex; class SrcFace; struct ScrUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType>{}; class SrcVertex : public vcg::Vertex < ScrUsedTypes, vcg::vertex::InfoOcf, vcg::vertex::Coord3f, vcg::vertex::TexCoordfOcf, vcg::vertex::BitFlags > { }; class SrcFace : public vcg::Face < ScrUsedTypes, vcg::face::InfoOcf, vcg::face::VertexRef, vcg::face::WedgeTexCoordfOcf > { }; class SrcMesh : public vcg::tri::TriMesh , vcg::face::vector_ocf > { }; typedef SrcVertex DstVertex; typedef SrcFace DstFace; typedef SrcMesh DstMesh; #else // source mesh type: per-wedge texture coordinates class SrcVertex; class SrcFace; struct SrcUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType>{}; class SrcVertex : public vcg::Vertex { }; class SrcFace : public vcg::Face { }; class SrcMesh : public vcg::tri::TriMesh , std::vector > { }; // destination mesh type: per-vertex texture coordinates class DstVertex; class DstFace; struct DstUsedTypes : public UsedTypes< Use::AsVertexType, Use::AsFaceType>{}; class DstVertex : public vcg::Vertex { }; class DstFace : public vcg::Face { }; class DstMesh : public vcg::tri::TriMesh , std::vector > { }; #endif // extract wedge attributes functor. // given a source face and a wedge index, this functor extracts all the relevant attributes from the wedge // and transfer them to the destination vertex. // source and destination meshes are provided to allow for attribute presence checking (.Is*Enabled()). inline void ExtractVertex(const SrcMesh & srcMesh, const SrcFace & f, int whichWedge, const DstMesh & dstMesh, DstVertex & v) { (void)srcMesh; (void)dstMesh; v.P() = f.cP(whichWedge); v.T() = f.cWT(whichWedge); } // sample compare functor. // given two destination vertices, this functor tells if they are identical in all relevan attributes. // source and destination meshes are provided to allow for attribute presence checking (.Is*Enabled()). inline bool CompareVertex(const DstMesh & m, const DstVertex & vA, const DstVertex & vB) { (void)m; return (vA.cT() == vB.cT()); } // sample copy functor. // given two destination vertices, this functor is asked to copy all relevan attributes. // source and destination meshes are provided to allow for attribute presence checking (.Is*Enabled()). inline void CopyVertex(const DstMesh & m, const DstVertex & vSrc, DstVertex & vDst) { (void)m; vDst.P() = vSrc.cP(); vDst.T() = vSrc.cT(); } void usage(void) { printf("usage : trimesh_split_vertex \n"); printf("where : : source PLY trimesh file name with texture coordinates per wedge\n"); printf(" : destination PLY trimesh file name with texture coordinates per vertex\n"); printf("exit.\n"); } int main(int argc, char ** argv) { if (argc != 3) { usage(); return -1; } SrcMesh srcMesh; #ifdef TEST_IN_PLACE_SPLIT srcMesh.face.EnableWedgeTex(); #endif vcg::tri::io::ImporterPLY::Open(srcMesh, argv[1]); if ((srcMesh.vn <= 0) || (srcMesh.fn <= 0)) { printf("invalid source mesh file.\n"); return -1; } const int srcVN = srcMesh.vn; const int srcFN = srcMesh.fn; printf("source mesh succesfully loaded.\n"); #ifdef TEST_IN_PLACE_SPLIT DstMesh & dstMesh = srcMesh; dstMesh.vert.EnableTexCoord(); vcg::tri::AttributeSeam::SplitVertex(dstMesh, ExtractVertex, CompareVertex); #else DstMesh dstMesh; vcg::tri::AttributeSeam::SplitVertex(srcMesh, dstMesh, ExtractVertex, CompareVertex, CopyVertex); dstMesh.textures = srcMesh.textures; #endif if (vcg::tri::io::ExporterPLY::Save(dstMesh, argv[2], vcg::tri::io::Mask::IOM_VERTCOORD | vcg::tri::io::Mask::IOM_VERTTEXCOORD) != 0) { printf("cannot save destination mesh file.\n"); return -1; } printf("destination mesh succesfully saved.\n"); const int dstVN = dstMesh.vn; const int dstFN = dstMesh.fn; printf("\n"); printf("statistics:\n"); printf(" input mesh vertices count : %d\n", srcVN); printf(" input mesh faces count : %d\n", srcFN); printf(" splitted mesh vertices count : %d\n", dstVN); printf(" splitted mesh faces count : %d\n", dstFN); printf("\n"); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/polygonmesh_base/0000755000175000017500000000000012227522351022107 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/polygonmesh_base/polygonmesh.cpp0000644000175000017500000002147211551320477025171 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ #include /*include the base definition for the vertex */ #include /*include the base definition for the face */ #include /*include the base definition for the edge */ #include /*include the base definition for the trimesh*/ #include /*include the algorithms for updating: */ #include /* topology */ #include /* bounding box */ #include /* normal */ /*include the algorithms for mesh fixing */ #include /*include the importer from disk*/ #include /*include the exporter to disk (in ply)*/ #include /* include the support for polygon meshes (function to convert from/to trimesh)*/ #include /* include the support for polygon meshes (the component for the face )*/ #include /* include the support for half edges */ #include using namespace vcg; using namespace std; // forward declarations class CFace; class CVertex; class CHEdge; class CEdge; class MyPolyVertex; struct CUsedTypes: public vcg::UsedTypes< vcg::Use::AsVertexType, vcg::Use::AsFaceType >{}; /* Definition of a mesh of triangles */ class CVertex : public Vertex< CUsedTypes, vertex::BitFlags, vertex::Coord3f, vertex::Normal3f, vertex::Mark >{}; class CFace : public Face< CUsedTypes, face::VertexRef, // three pointers to vertices face::Normal3f, // normal face::BitFlags, // flags face::FFAdj // three pointers to adjacent faces > {}; /* the mesh is a container of vertices and a container of faces */ class CMesh : public vcg::tri::TriMesh< vector, vector > {}; /* Definition of a mesh of polygons that also supports half-edges */ class MyPolyFace; class MyPolyVertex; struct PolyUsedTypes: public vcg::UsedTypes ::AsVertexType, vcg::Use ::AsEdgeType, vcg::Use ::AsHEdgeType, vcg::Use ::AsFaceType >{}; //class DummyEdge: public vcg::Edge{}; class MyPolyVertex:public vcg::Vertex< PolyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::Mark, vcg::vertex::BitFlags, vcg::vertex::VHAdj>{} ; class CEdge : public Edge{}; class CHEdge : public HEdge< PolyUsedTypes, hedge::BitFlags, //hedge::HFAdj, // pointer to the face //hedge::HOppAdj, // pointer to the opposite edge //hedge::HVAdj, // pointer to the vertex //hedge::HNextAdj, // pointer to the next halfedge hedge::HEdgeData // the previous 4 components (just more handy, you can comment this and uncomment the previous four lines) //,hedge::HPrevAdj // pointer to the previous halfedge >{}; class MyPolyFace:public vcg::Face< PolyUsedTypes ,vcg::face::PolyInfo // this is necessary if you use component in vcg/simplex/face/component_polygon.h // It says "this class is a polygon and the memory for its components (e.g. pointer to its vertices // will be allocated dynamically") ,vcg::face::PFVAdj // Pointer to the vertices (just like FVAdj ) ,vcg::face::PFVAdj ,vcg::face::PFFAdj // Pointer to edge-adjacent face (just like FFAdj ) ,vcg::face::PFHAdj // Pointer its half -edges ( you may need this if you use half edges) ,vcg::face::BitFlags // bit flags ,vcg::face::Normal3f // normal > {}; class MyPolyMesh: public vcg::tri::TriMesh< std::vector, // the vector of vertices std::vector, // the vector of faces std::vector , // the vector of edges std::vector // the vector of edges >{}; MyPolyMesh pm; //////////////////////////////////////////////////////////////////////////// // Globals: the mesh, the OpenGL wrapper to draw the mesh and the trackball. CMesh mesh,mesh1; int main(int argc, char *argv[]) { int loadmask; vcg::tri::io::PlyInfo pi; // pm.hedge.reserve(100000); if(true){ /* first way: 1) read a polygon mesh that will be automatically converted in a triangle mesh tagging the internal edges (i.e. the edges that have been added for triangulating the polygons) 2) make some cleaning 3) import the tagged triangle mesh in a polygon mesh */ // vcg::tri::io::ImporterOBJ::Open(mesh,argv[1],loadmask); vcg::tri::io::ImporterOFF::Open(mesh,argv[1],loadmask); vcg::tri::Clean::RemoveUnreferencedVertex(mesh); vcg::tri::Clean::RemoveZeroAreaFace(mesh); vcg::tri::UpdateTopology::FaceFace(mesh); vcg::tri::Clean::RemoveNonManifoldFace(mesh); vcg::tri::UpdateTopology::FaceFace(mesh); assert(vcg::tri::Clean::CountNonManifoldEdgeFF(mesh)==0); assert(vcg::tri::Clean::CountNonManifoldVertexFF(mesh)==0); // create a polygon meshe from a trimesh with tagged faces vcg::tri::PolygonSupport::ImportFromTriMesh(pm,mesh); } else { /* second way: Load into a polygon mesh straight away. */ vcg::tri::io::ImporterOBJ::Open(pm,argv[1],loadmask); vcg::tri::UpdateTopology::FaceFace(pm); vcg::tri::Clean::RemoveNonManifoldFace(pm); vcg::tri::UpdateTopology::FaceFace(pm); assert(vcg::tri::Clean::CountNonManifoldEdgeFF(pm)); } // compute the half edges because I'm a half-edge programmer vcg::tri::UpdateHalfEdges::FromIndexed(pm); // .... my half edge based code ...... // check for consistency assert(vcg::tri::UpdateHalfEdges::CheckConsistency(pm)); int size = pm.face.size(); // add a face to each face with more than 3 vertices ( just one pass) for(int i = 0; i < size; ++i) if(!(pm.face[i].IsD())) if(pm.face[i].VN()>3){ MyPolyMesh::HEdgePointer ef = pm.face[i].FHp(); MyPolyMesh::HEdgePointer ef1 = ef -> HNp(); ef1 = ef1->HNp(); vcg::tri::UpdateHalfEdges::AddHEdge(pm, ef, ef1 ); } assert(vcg::tri::UpdateHalfEdges::CheckConsistency(pm)); size = pm.face.size(); // remove an edge for each face for(int i = 0; i < size; ++i) if(!(pm.face[i].IsD() )) { MyPolyMesh::HEdgePointer ef = pm.face[i].FHp(); if( ef->HOp()->HFp() !=NULL){ vcg::tri::UpdateHalfEdges::RemoveHEdge(pm,ef); } } // check for consistency assert(vcg::tri::UpdateHalfEdges::CheckConsistency(pm)); // recompute indexed data structure from the half edge data structure vcg::tri::UpdateIndexed::FromHalfEdges(pm ); // create a triangle mesh from a polygon mesh vcg::tri::PolygonSupport::ImportFromPolyMesh(mesh1,pm); // write out the triangle mesh vcg::tri::io::ExporterPLY::Save(mesh1,"converted_out.ply",true,pi); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/polygonmesh_base/polygonmesh_base.pro0000644000175000017500000000060211551320477026171 0ustar gladkgladk###################################################################### # Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 ###################################################################### TARGET = polygonmesh_base DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += polygonmesh.cpp ../../../wrap/ply/plylib.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ant_freeglut/0000755000175000017500000000000012227522351022763 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ant_freeglut/trimesh_ant_freeglut.pro0000644000175000017500000000155511551320500027714 0ustar gladkgladk# Base options TEMPLATE = app LANGUAGE = C++ # Executable name TARGET = trimesh_ant_freeglut # Directories DESTDIR = . OBJECTS_DIR = build/obj # Lib headers INCLUDEPATH += . INCLUDEPATH += ../../.. # Lib sources SOURCES += ../../../wrap/ply/plylib.cpp SOURCES += ../../../wrap/gui/trackball.cpp SOURCES += ../../../wrap/gui/trackmode.cpp # Compile glew DEFINES += GLEW_STATIC SOURCES += ../../../../code/lib/glew/src/glew.c # Awful problem with windows.. win32{ DEFINES += NOMINMAX INCLUDEPATH += ../../../../code/lib/glew/include INCLUDEPATH += ../../../../code/lib/AntTweakBar/include INCLUDEPATH += ../../../../code/lib/freeglut/include LIBS +=../../../../code/lib/AntTweakBar/lib/AntTweakBar.lib LIBS +=../../../../code/lib/freeglut/lib/freeglut.lib } unix { LIBS += -lfreeglut } # Input SOURCES += main.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_ant_freeglut/main.cpp0000644000175000017500000002604011634102552024413 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2007 \/)\/ * * 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. * * * ****************************************************************************/ /** * Minimal trimesh viewer made with AntTweakBar and freglut * * This sample shows how to use togheter: * - the trimesh loading and initialization * - basic usage of the default manipulators (the "Trackball") */ #include #include #include #include /// vcg imports #include #include #include #include #include #include /// wrapper imports #include #include #include /// declaring edge and face type using namespace vcg; class CFace; class CVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsFaceType>{}; /// compositing wanted proprieties class CVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f, vcg::vertex::Normal3f, vcg::vertex::BitFlags>{}; class CFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags > {}; class CMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; /// the active mesh instance CMesh mesh; /// filename of the mesh to load char * filename = NULL; /// the active mesh opengl wrapper vcg::GlTrimesh glWrap; /// the active manipulator vcg::Trackball track; /// window size int width,height; /// we choosed a subset of the avaible drawing modes enum DrawMode{SMOOTH=0,PERPOINTS,WIRE,FLATWIRE,HIDDEN,FLAT}; /// the current drawmode DrawMode drawmode; /// Takes a GLUT MouseButton and returns the equivalent Trackball::Button static vcg::Trackball::Button GLUT2VCG (int glut_button, int ) { int vcgbt = vcg::Trackball::BUTTON_NONE; switch(glut_button){ case GLUT_LEFT_BUTTON: vcgbt |= vcg::Trackball::BUTTON_LEFT; break; case GLUT_MIDDLE_BUTTON: vcgbt |= vcg::Trackball::BUTTON_RIGHT; break; case GLUT_RIGHT_BUTTON: vcgbt |= vcg::Trackball::BUTTON_MIDDLE; break; } int modifiers = glutGetModifiers(); if (modifiers & GLUT_ACTIVE_SHIFT) vcgbt |= vcg::Trackball::KEY_SHIFT; if (modifiers & GLUT_ACTIVE_CTRL) vcgbt |= vcg::Trackball::KEY_CTRL; if (modifiers & GLUT_ACTIVE_ALT) vcgbt |= vcg::Trackball::KEY_ALT; return vcg::Trackball::Button (vcgbt); } void Display(){ glViewport(0, 0, width, height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if(!mesh.face.empty()){ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40, width /(float) height , 0.1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,5, 0,0,0, 0,1,0); track.center=vcg::Point3f(0, 0, 0); track.radius= 1; track.GetView(); track.Apply(false); glPushMatrix(); float d=1.0f/mesh.bbox.Diag(); vcg::glScale(d); glTranslate(-glWrap.m->bbox.Center()); // the trimesh drawing calls switch(drawmode) { case SMOOTH: glWrap.Draw (); break; case PERPOINTS: glWrap.Draw (); break; case WIRE: glWrap.Draw (); break; case FLATWIRE: glWrap.Draw (); break; case HIDDEN: glWrap.Draw (); break; case FLAT: glWrap.Draw (); break; default: break; } glPopMatrix(); track.DrawPostApply(); } TwDraw(); // Present frame buffer glutSwapBuffers(); // Recall Display at next frame glutPostRedisplay(); } void Reshape(int _width,int _height){ width = _width ; height = _height; TwWindowSize(width, height); } void Terminate(){} void initMesh() { // update bounding box vcg::tri::UpdateBounding::Box(mesh); // update Normals vcg::tri::UpdateNormals::PerVertexNormalizedPerFace(mesh); vcg::tri::UpdateNormals::PerFaceNormalized(mesh); // Initialize the opengl wrapper glWrap.m = &mesh; glWrap.Update(); } void TW_CALL loadMesh(void *) { if(filename==0) return; int err=vcg::tri::io::ImporterPLY::Open(mesh,(char*)filename); if(err!=0){ const char* errmsg=vcg::tri::io::ImporterPLY::ErrorMsg(err); } else initMesh(); } void TW_CALL loadTetrahedron(void *){ vcg::tri::Tetrahedron(mesh); initMesh(); } void TW_CALL loadDodecahedron(void * ){ vcg::tri::Dodecahedron(mesh); initMesh(); } void keyReleaseEvent (unsigned char k,int x,int y) { int modifiers = glutGetModifiers(); if (modifiers & GLUT_ACTIVE_CTRL) track.ButtonUp (Trackball::Button::KEY_CTRL); if (modifiers & GLUT_ACTIVE_SHIFT) track.ButtonUp ( Trackball::Button::KEY_SHIFT); if (modifiers & GLUT_ACTIVE_ALT) track.ButtonUp (Trackball::Button::KEY_ALT); } void keyPressEvent (unsigned char k,int x,int y) { int modifiers = glutGetModifiers(); if (modifiers & GLUT_ACTIVE_CTRL) track.ButtonDown (Trackball::Button::KEY_CTRL); if (modifiers & GLUT_ACTIVE_SHIFT) track.ButtonDown ( Trackball::Button::KEY_SHIFT); if (modifiers & GLUT_ACTIVE_ALT) track.ButtonDown (Trackball::Button::KEY_ALT); TwEventKeyboardGLUT(k,x,y); } void mousePressEvent(int bt,int state,int x,int y){ if(state == GLUT_DOWN) track.MouseDown ( x , height - y , GLUT2VCG (bt,state)); else track.MouseUp ( x , height - y , GLUT2VCG (bt,state)); TwEventMouseButtonGLUT(bt,state,x,y); }; void mouseMoveEvent (int x, int y ) { if(!TwEventMouseMotionGLUT(x,y)) track.MouseMove ( x , height - y ); } //void mouseReleaseEvent(QMouseEvent*e); void wheelEvent(int wheel, int direction, int x, int y ){ track.MouseWheel(wheel*direction); } void TW_CALL CopyCDStringToClient(char **destPtr, const char *src) { size_t srcLen = (src!=NULL) ? strlen(src) : 0; size_t destLen = (*destPtr!=NULL) ? strlen(*destPtr) : 0; // Alloc or realloc dest memory block if needed if( *destPtr==NULL ) *destPtr = (char *)malloc(srcLen+1); else if( srcLen>destLen ) *destPtr = (char *)realloc(*destPtr, srcLen+1); // Copy src if( srcLen>0 ) strncpy(*destPtr, src, srcLen); (*destPtr)[srcLen] = '\0'; // null-terminated string } int main(int argc, char *argv[]) { TwBar *bar; // Pointer to the tweak bar // Initialize AntTweakBar // (note that AntTweakBar could also be intialized after GLUT, no matter) if( !TwInit(TW_OPENGL, NULL) ) { // A fatal error occured fprintf(stderr, "AntTweakBar initialization failed: %s\n", TwGetLastError()); return 1; } glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(640, 480); glutCreateWindow("AntTweakBar simple example using GLUT"); glutCreateMenu(NULL); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); // Set GLUT callbacks glutDisplayFunc(Display); glutReshapeFunc(Reshape); atexit(Terminate); // Called after glutMainLoop ends // Set GLUT event callbacks // - Directly redirect GLUT mouse button events to AntTweakBar glutMouseFunc((GLUTmousebuttonfun)mousePressEvent); // - Directly redirect GLUT mouse motion events to AntTweakBar glutMotionFunc((GLUTmousemotionfun)mouseMoveEvent); // - Directly redirect GLUT mouse "passive" motion events to AntTweakBar (same as MouseMotion) glutPassiveMotionFunc((GLUTmousemotionfun)TwEventMouseMotionGLUT); // - Directly redirect GLUT key events to AntTweakBar glutKeyboardFunc((GLUTkeyboardfun)TwEventKeyboardGLUT); // - Directly redirect GLUT special key events to AntTweakBar glutSpecialFunc((GLUTspecialfun)TwEventSpecialGLUT); glutKeyboardFunc(keyPressEvent); glutKeyboardUpFunc(keyReleaseEvent); glutMouseWheelFunc(wheelEvent); bar = TwNewBar("TweakBar"); TwCopyCDStringToClientFunc (CopyCDStringToClient); TwAddVarRW(bar,"Input",TW_TYPE_CDSTRING,&filename," label='Filepath' group=SetMesh help=` Name of the file to load` "); TwAddButton(bar,"Load from file",loadMesh,0, " label='Load Mesh' group=SetMesh help=`load the mesh` "); TwAddButton(bar,"Use tetrahedron",loadTetrahedron,0, " label='Make Tetrahedron' group=SetMesh help=`use tetrahedron.` "); TwAddButton(bar,"Use dodecahedron",loadDodecahedron,0, " label='Make Dodecahedron' group=SetMesh help=`use dodecahedron.` "); // ShapeEV associates Shape enum values with labels that will be displayed instead of enum values TwEnumVal drawmodes[6] = { {SMOOTH, "Smooth"}, {PERPOINTS, "Per Points"}, {WIRE, "Wire"}, {FLATWIRE, "FlatWire"},{HIDDEN, "Hidden"},{FLAT, "Flat"}}; // Create a type for the enum shapeEV TwType drawMode = TwDefineEnum("DrawMode", drawmodes, 6); // add 'g_CurrentShape' to 'bar': this is a variable of type ShapeType. Its key shortcuts are [<] and [>]. TwAddVarRW(bar, "Draw Mode", drawMode, &drawmode, " keyIncr='<' keyDecr='>' help='Change draw mode.' "); glutMainLoop(); } meshlab-1.3.2+dfsg1/vcglib/apps/sample/colorspace/0000755000175000017500000000000012227522351020703 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/colorspace/colorspace.pro0000644000175000017500000000021211517500567023560 0ustar gladkgladkTARGET = colorspace LIBPATH += DEPENDPATH += . INCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app SOURCES += colorspace.cppmeshlab-1.3.2+dfsg1/vcglib/apps/sample/colorspace/colorspace.cpp0000644000175000017500000001000411517500567023542 0ustar gladkgladk // Standard headers #include // VCG headers #include #include using namespace std; typedef vcg::ColorSpace ColorSpace; int main(int argc,char ** argv) { // Some Color Space processing examples cout << endl; if (argc != 4) { cout << " Usage: colorspace " << endl << endl; cout << " : RGB triplet (0-255)" << endl << endl; cout << " Note: The RGB triplet is assumed in the sRGB space (D65 illuminant)."; cout << endl << endl; exit(-2); } double r = static_cast(atof(argv[1])); double g = static_cast(atof(argv[2])); double b = static_cast(atof(argv[3])); // RGB components have to be in the range [0.0, 1.0] vcg::Color4 color(r/255.0, g/255.0, b/255.0, 0.0); // RGB --> RGB (RGB space changing) /////////////////////////////////////////////// cout << " * RGB --> RGB conversion" << endl << endl; vcg::Color4 rgb = ColorSpace::RGBtoRGB(color, ColorSpace::SRGB, ColorSpace::PAL_RGB); rgb *= 255.0; cout << " RGB (PAL/SECAM): " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl; rgb = ColorSpace::RGBtoRGB(color, ColorSpace::SRGB, ColorSpace::WIDE_GAMUT); rgb *= 255.0; cout << " RGB (Wide Gamut): " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl << endl; // RGB <--> HSL (Hue, Saturation, Lightness) /////////////////////////////////////////////// cout << " * RGB <--> HSL conversion" << endl << endl; vcg::Color4 hsl = ColorSpace::RGBtoHSL(color); cout << " RGB --> HSL: " << hsl[0]*360.0 << "° " << hsl[1]*100.0 << "% " << hsl[2]*100.0 << "% " << endl; rgb = ColorSpace::HSLtoRGB(hsl); rgb *= 255.0; cout << " HSL --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl << endl; // RGB <--> HSV (Hue, Saturation, Value) /////////////////////////////////////////////// cout << " * RGB <--> HSV conversion" << endl << endl; vcg::Color4 hsv = ColorSpace::RGBtoHSV(color); cout << " RGB --> HSV: " << hsv[0]*360.0 << "° " << hsv[1]*100.0 << "% " << hsv[2]*100.0 << "% " << endl; rgb = ColorSpace::HSVtoRGB(hsv); rgb *= 255.0; cout << " HSV --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl << endl; // RGB --> CIELab /////////////////////////////////////////////// cout << " * RGB <--> Lab conversion" << endl << endl; vcg::Color4 xyzD65 = ColorSpace::RGBtoXYZ(color, ColorSpace::SRGB, ColorSpace::ILLUMINANT_D65); vcg::Color4 lab = ColorSpace::XYZtoCIELab(xyzD65, ColorSpace::refIlluminant(ColorSpace::SRGB)); cout << " RGB --> CIELab: " << lab[0] << " " << lab[1] << " " << lab[2] << endl; vcg::Color4 xyz = ColorSpace::CIELabtoXYZ(lab, ColorSpace::refIlluminant(ColorSpace::SRGB)); rgb = ColorSpace::XYZtoRGB(xyz, ColorSpace::refIlluminant(ColorSpace::SRGB), ColorSpace::SRGB); rgb *= 255.0; cout << " CIELab --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl << endl; // RGB <--> XYZ /////////////////////////////////////////////// cout << " * RGB <--> XYZ conversion" << endl << endl; // RGB --> XYZ (D65) cout << " RGB --> XYZ (D65): " << xyzD65[0] << " " << xyzD65[1] << " " << xyzD65[2] << endl; // XYZ (D65) --> RGB rgb = ColorSpace::XYZtoRGB(xyzD65, ColorSpace::ILLUMINANT_D65, ColorSpace::SRGB); rgb *= 255.0; cout << " XYZ (D65) --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl; // RGB --> XYZ (D50) vcg::Color4 xyzD50 = ColorSpace::RGBtoXYZ(color, ColorSpace::SRGB, ColorSpace::ILLUMINANT_D50); cout << " RGB --> XYZ (D50): " << xyzD50[0] << " " << xyzD50[1] << " " << xyzD50[2] << endl; // XYZ (D50) --> RGB rgb = ColorSpace::XYZtoRGB(xyzD50, ColorSpace::ILLUMINANT_D50, ColorSpace::SRGB); rgb *= 255.0; cout << " XYZ (D50) --> RGB: " << rgb[0] << " " << rgb[1] << " " << rgb[2] << endl; // Direct way xyz = ColorSpace::chromaticAdaptation(xyzD65, ColorSpace::ILLUMINANT_D65, ColorSpace::ILLUMINANT_D50); cout << " XYZ (D65 --> D50): " << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl << endl; return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_isosurface/0000755000175000017500000000000012227522351022447 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_isosurface/trimesh_isosurface.pro0000644000175000017500000000020611551320477027071 0ustar gladkgladkINCLUDEPATH += . ../../.. CONFIG += console stl TEMPLATE = app # Input SOURCES += trimesh_isosurface.cpp ../../../wrap/ply/plylib.cpp meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_isosurface/trimesh_isosurface.cpp0000644000175000017500000000337411651743672027073 0ustar gladkgladk#include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace vcg; typedef float ScalarType; class MyFace; class MyVertex; struct MyUsedTypes : public UsedTypes< Use ::AsVertexType, Use ::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f>{}; class MyFace : public Face< MyUsedTypes, face::VertexRef, face::BitFlags> {}; class MyMesh : public vcg::tri::TriMesh< std::vector< MyVertex>, std::vector< MyFace > > {}; typedef SimpleVolume MyVolume; int main(int /*argc*/ , char /**argv[]*/) { MyVolume volume; typedef vcg::tri::TrivialWalker MyWalker; typedef vcg::tri::MarchingCubes MyMarchingCubes; MyWalker walker; // Simple initialization of the volume with some cool perlin noise volume.Init(Point3i(64,64,64)); for(int i=0;i<64;i++) for(int j=0;j<64;j++) for(int k=0;k<64;k++) volume.Val(i,j,k)=(j-32)*(j-32)+(k-32)*(k-32) + i*10*(float)math::Perlin::Noise(i*.2,j*.2,k*.2); // MARCHING CUBES MyMesh mc_mesh; printf("[MARCHING CUBES] Building mesh..."); MyMarchingCubes mc(mc_mesh, walker); walker.BuildMesh(mc_mesh, volume, mc, 20*20); vcg::tri::io::ExporterPLY::Save( mc_mesh, "marching_cubes.ply"); printf("OK!\n"); }; meshlab-1.3.2+dfsg1/vcglib/apps/sample/trimesh_isosurface/simple_volume.h0000644000175000017500000000520411517500567025507 0ustar gladkgladk#ifndef __VCG_SIMPLE_VOLUME #define __VCG_SIMPLE_VOLUME #include namespace vcg { template class SimpleVolume { public: typedef VOX_TYPE VoxelType; std::vector Vol; Point3i sz; /// Dimensioni griglia come numero di celle per lato const Point3i &ISize() {return sz;}; /// Dimensioni griglia come numero di celle per lato void Init(Point3i _sz) { sz=_sz; Vol.resize(sz[0]*sz[1]*sz[2]); } float Val(const int &x,const int &y,const int &z) const { return cV(x,y,z).V(); //else return numeric_limits::quiet_NaN( ); } float &Val(const int &x,const int &y,const int &z) { return V(x,y,z).V(); //else return numeric_limits::quiet_NaN( ); } VOX_TYPE &V(const int &x,const int &y,const int &z) { return Vol[x+y*sz[0]+z*sz[0]*sz[1]]; } const VOX_TYPE &cV(const int &x,const int &y,const int &z) const { return Vol[x+y*sz[0]+z*sz[0]*sz[1]]; } typedef enum { XAxis=0,YAxis=1,ZAxis=2} VolumeAxis; template < class VertexPointerType, VolumeAxis AxisVal > void GetIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointerType &v, const float thr) { float f1 = Val(p1.X(), p1.Y(), p1.Z())-thr; float f2 = Val(p2.X(), p2.Y(), p2.Z())-thr; float u = (float) f1/(f1-f2); if(AxisVal==XAxis) v->P().X() = (float) p1.X()*(1-u) + u*p2.X(); else v->P().X() = (float) p1.X(); if(AxisVal==YAxis) v->P().Y() = (float) p1.Y()*(1-u) + u*p2.Y(); else v->P().Y() = (float) p1.Y(); if(AxisVal==ZAxis) v->P().Z() = (float) p1.Z()*(1-u) + u*p2.Z(); else v->P().Z() = (float) p1.Z(); } template < class VertexPointerType > void GetXIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointerType &v, const float thr) { GetIntercept(p1,p2,v,thr); } template < class VertexPointerType > void GetYIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointerType &v, const float thr) { GetIntercept(p1,p2,v,thr); } template < class VertexPointerType > void GetZIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointerType &v, const float thr) { GetIntercept(p1,p2,v,thr); } }; template class RawVolumeImporter { public: enum DataType { // Funzioni superiori UNDEF=0, BYTE=1, SHORT=2, FLOAT=3 }; static bool Open(const char *filename, VolumeType &V, Point3i sz, DataType d) { return true; } }; class SimpleVoxel { private: float _v; public: float &V() {return _v;}; float V() const {return _v;}; }; } // end namespace #endif // __VCG_SIMPLE_VOLUMEmeshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/0000755000175000017500000000000012227522351017617 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/defs.h0000644000175000017500000000477511517500600020720 0ustar gladkgladk// ----------------------------------------------------------------------------------------------- #ifndef _DEFS_H #define _DEFS_H // ----------------------------------------------------------------------------------------------- // command line parameters #define CMD_LINE_ARG_HIST 'H' #define CMD_LINE_ARG_VERTEX_SAMPLE 'V' #define CMD_LINE_ARG_EDGE_SAMPLE 'E' #define CMD_LINE_ARG_FACE_SAMPLE 'F' #define CMD_LINE_ARG_SAMPLE_TYPE 'S' #define CMD_LINE_ARG_MONTECARLO_SAMPLING 'M' #define CMD_LINE_ARG_SUBDIVISION_SAMPLING 'S' #define CMD_LINE_ARG_SIMILAR_TRIANGLES_SAMPLING 'T' #define CMD_LINE_ARG_N_SAMPLES 'N' #define CMD_LINE_ARG_SAMPLES_PER_AREA_UNIT 'A' #define CMD_LINE_ARG_SAVE_DISPLACEMENT 'O' #define CMD_LINE_ARG_SAVE_ERROR_AS_COLOUR 'C' // error messages #define MSG_ERR_N_ARGS " Usage:\n\n" \ " trimeshinfo [options]\n\n" \ " Options:\n\n" \ " -q Quiet (disable verbose mode that is enabled by default)\n" \ " -x Enable XML output\n" \ " -h Enable HTML output\n" \ " -s Save the clean mesh\n\n" #define MSG_ERR_MESH_LOAD "error loading the input meshes.\n" #define MSG_ERR_INVALID_OPTION "unable to parse option '%s'\n" #define MSG_ERR_FILE_OPEN "unable to open the output file.'n" #define MSG_ERR_UNKNOWN_FORMAT "unknown file format '%s'.\n" // global constants #define NO_SAMPLES_PER_FACE 10 #define N_SAMPLES_EDGE_TO_FACE_RATIO 0.1 #define BBOX_FACTOR 0.1 #define INFLATE_PERCENTAGE 0.02 #define MIN_SIZE 125 /* 125 = 5^3 */ #define N_HIST_BINS 256 #define PRINT_EVERY_N_ELEMENTS 1000 #define FILE_EXT_SMF "smf" #define FILE_EXT_PLY "ply" // strings #define STR_HIST_FILENAME_DEFAULT "hist.txt" #define STR_NEW_MESH_FILENAME_DEFAULT "error.ply" #define STR_NEW_MESH_FILENAME_DEFAULT_2 "error_colour.ply" // ----------------------------------------------------------------------------------------------- #endif // ----------------------------------------------------------------------------------------------- meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.01/0000755000175000017500000000000012227522351022446 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.01/trimeshinfosample/0000755000175000017500000000000012227522351026177 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.01/trimeshinfosample/readme.txt0000644000175000017500000000131411517500571030175 0ustar gladkgladkThis directory contains six 3d models that can be used to test trimeshinfo. The models represent a toroidal knot at two different level of details: - knot_orig.ply 12800 vertexes, 25600 triangles: the original high resolution mesh - knot_subsampled.ply 800 vertexes, 1600 triangles: a low res model obtained by simple uniform subsampling - knot_vcg_simplified.ply 800 vertexes, 1600 triangles: a low res model obtained by our library simplification code a low resolution model of the Kleine bottle: - kleine.ply 255 vertexes, 520 triangles two low resolution models of the moebius strip: - moebius.ply 80 vertexes, 160 triangles - moebius_big.ply 320 vertexes, 480 triangles meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.01/trimeshinfo101/0000755000175000017500000000000012227522351025217 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.01/trimeshinfo101/defs.h0000644000175000017500000000416211517500570026314 0ustar gladkgladk// ----------------------------------------------------------------------------------------------- #ifndef _DEFS_H #define _DEFS_H // ----------------------------------------------------------------------------------------------- // command line parameters #define CMD_LINE_ARG_HIST 'H' #define CMD_LINE_ARG_VERTEX_SAMPLE 'V' #define CMD_LINE_ARG_EDGE_SAMPLE 'E' #define CMD_LINE_ARG_FACE_SAMPLE 'F' #define CMD_LINE_ARG_SAMPLE_TYPE 'S' #define CMD_LINE_ARG_MONTECARLO_SAMPLING 'M' #define CMD_LINE_ARG_SUBDIVISION_SAMPLING 'S' #define CMD_LINE_ARG_SIMILAR_TRIANGLES_SAMPLING 'T' #define CMD_LINE_ARG_N_SAMPLES 'N' #define CMD_LINE_ARG_SAMPLES_PER_AREA_UNIT 'A' #define CMD_LINE_ARG_SAVE_DISPLACEMENT 'O' #define CMD_LINE_ARG_SAVE_ERROR_AS_COLOUR 'C' // error messages #define MSG_ERR_N_ARGS "\nUsage: "\ "trimeshinfo filename \n" #define MSG_ERR_MESH_LOAD "error loading the input meshes.\n" #define MSG_ERR_INVALID_OPTION "unable to parse option '%s'\n" #define MSG_ERR_FILE_OPEN "unable to open the output file.'n" #define MSG_ERR_UNKNOWN_FORMAT "unknown file format '%s'.\n" // global constants #define NO_SAMPLES_PER_FACE 10 #define N_SAMPLES_EDGE_TO_FACE_RATIO 0.1 #define BBOX_FACTOR 0.1 #define INFLATE_PERCENTAGE 0.02 #define MIN_SIZE 125 /* 125 = 5^3 */ #define N_HIST_BINS 256 #define PRINT_EVERY_N_ELEMENTS 1000 #define FILE_EXT_SMF "smf" #define FILE_EXT_PLY "ply" // strings #define STR_HIST_FILENAME_DEFAULT "hist.txt" #define STR_NEW_MESH_FILENAME_DEFAULT "error.ply" #define STR_NEW_MESH_FILENAME_DEFAULT_2 "error_colour.ply" // ----------------------------------------------------------------------------------------------- #endif // ----------------------------------------------------------------------------------------------- meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.01/trimeshinfo101/resource.h0000644000175000017500000000074211517500570027222 0ustar gladkgladk//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by trimeshinfo.rc // #define IDI_ICON1 112 #define IDI_ICON2 113 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 114 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.01/trimeshinfo101/readme.txt0000644000175000017500000000575611517500570027232 0ustar gladkgladk VCGLib http://vcg.sf.net o o Visual and Computer Graphics Library o o _ O _ Copyright(C) 2004-2005 \/)\/ Visual Computing Lab http://vcg.isti.cnr.it /\/| ISTI - Italian National Research Council | \ TriMeshInfo 1.01 14/02/2005 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. --- Synopsis --- TriMeshInfo is a tool designed to inspect 3D models and retrieve all the topological related information. It can be used to automate the process of decoding 3D mesh inherent properties and ease data classification and retrieval. For each analyzed dataset the following information are extracted: * Number of Vertices (Unreferenced vertices are listed separately) * Number of Faces * Number of Edges * Number of Connected Components * Number of Boundaries * Number of Isolated Vertices (i.e. Unreferenced) * Manifold * Volume (Computed only for Closed Manifold Datasets) * Color (Computed only if the information is embedded in the model) * Genus (Computed only for Manifold Datasets) * Orientability * Orientation * Regularity (We consider as regular those meshes generated through regular subdivision. Each non boundary vertex of a regular mesh has 6 incident edges, if there are only 5 incident edges the mesh is said to be semi-regular, irregular in all other cases) * Number of Duplicated Vertices * Self-Intersection (Currently computed only for Datasets with less than 3M faces) The application has no graphical interface but works as the "Metro" tool on command line. The application works under both Windows and Linux/Unix platforms. TriMeshInfo is written in C++ and makes use of the VCL library. The tool supports two file formats ply (as described in the following document http://vcg.sourceforge.net/img/wiki_up/plyformat.pdf) and off (as described in http://www.geomview.org/docs/html/geomview_41.html#SEC44) . meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.01/trimeshinfo101/main.cpp0000644000175000017500000003610511551320500026643 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.7 2005/02/07 15:44:31 rita_borgo Fixed Color and Volume Revision 1.6 2005/02/01 17:37:53 rita_borgo Fixed Volume and Color Revision 1.5 2005/01/18 16:33:12 rita_borgo Added OFF file Option Revision 1.4 2005/01/17 18:19:00 rita_borgo Added new routines. Self-intersection first release Revision 1.2 2005/01/03 16:13:09 rita_borgo Added Standard comments ****************************************************************************/ #include #include #include using namespace std; #include #include #include #include // mi sembra di averlo aggiunto! #include #include #include #include #include #include #include #include #include // loader #include #include "defs.h" using namespace vcg; using namespace tri; using namespace face; class MyFace; class MyEdge; class MyVertex:public Vertex{}; class MyFace :public FaceAFAV{}; class MyMesh: public tri::TriMesh< std::vector, std::vector >{}; void OpenMesh(const char *filename, MyMesh &m) { int err = tri::io::Importer::Open(m,filename); if(err) { printf("Error in reading %s: '%s'\n",filename,tri::io::Importer::ErrorMsg(err)); exit(-1); } printf("read mesh `%s'\n", filename); } inline char* GetExtension(char* filename) { for(int i=strlen(filename)-1; i >= 0; i--) if(filename[i] == '.') break; if(i > 0) return &(filename[i+1]); else return NULL; } typedef MyMesh::VertexPointer VertexPointer; typedef MyMesh::VertexIterator VertexIterator; /* classe di confronto per l'algoritmo di individuazione vertici duplicati*/ template class DuplicateVert_Compare{ public: inline bool operator() (VertexIterator a, VertexIterator b) { return *a < *b; } }; static int DuplicateVertex( MyMesh & m ) // V1.0 { if(m.vert.size()==0 || m.vn==0) return 0; std::map mp; int i,j; VertexIterator vi; int deleted=0; int k=0; int num_vert = m.vert.size(); vector perm(num_vert); for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi, ++k) perm[k] = &(*vi); DuplicateVert_Compare c_obj; std::sort(perm.begin(),perm.end(),c_obj); j = 0; i = j; mp[perm[i]] = perm[j]; ++i; for(;i!=num_vert;) { if( (! (*perm[i]).IsD()) && (! (*perm[j]).IsD()) && (*perm[i]).P() == (*perm[j]).cP() ) { VertexPointer t = perm[i]; mp[perm[i]] = perm[j]; ++i; (*t).SetD(); deleted++; } else { j = i; ++i; } } return deleted; } void main(int argc,char ** argv){ char *fmt; MyMesh m; bool DEBUG = false; //load the mesh //argv[1]=(char*)"c:\\checkup\\debug\\column1m.ply"; //argv[1] = "C:\\sf\\apps\\msvc\\trimeshinfo\\Release\\prism.off"; //argv[1] = "C:\\sf\\apps\\msvc\\trimeshinfo\\Release\\prova1.ply"; // print program info printf("-------------------------------\n" " TriMeshInfo V.1.01 \n" " http://vcg.isti.cnr.it\n" " release date: "__DATE__"\n" "-------------------------------\n\n"); if(DEBUG) argv[1] = "C:\\sf\\apps\\msvc\\trimeshinfo\\Release\\cube1.stl"; else { // load input meshes. if(argc <= 1) { printf(MSG_ERR_N_ARGS); exit(-1); } } OpenMesh(argv[1],m); FILE * index; index = fopen((string(argv[1])+string("2.html")).c_str(),"w"); fprintf(index,"

Mesh info: %s

\n\n\n", argv[1]); fprintf(index,"

GENERAL INFO

\n\n"); fprintf(index,"

Number of vertices: %d

\n", m.vn); fprintf(index,"

Number of faces: %d

\n", m.fn); printf("Mesh info:\n"); printf(" M: '%s'\n\t Number of vertices: %d \n", argv[1], m.vn); printf("\t Number of faces: %d \n", m.fn); if(m.HasPerFaceColor()||m.HasPerVertexColor()) { Color4b Color=m.C(); fprintf(index, "

Object color(4b): %f %f %f

\n\n", Color[0], Color[1], Color[2]); printf( "\t Object color(4b): %f %f %f \n", Color[0], Color[1], Color[2]); } vcg::tri::UpdateTopology::FaceFace(m); // IS MANIFOLD MyMesh::FaceIterator f; MyMesh::FaceIterator g; vcg::face::Pos he; vcg::face::Pos hei; int j; int man=0; bool Manifold = true; MyMesh::FaceIterator prova; prova = m.face.end(); for(f=m.face.begin();f!=m.face.end();++f) { for (j=0;j<3;++j) { if(!IsManifold(*f,j)) { Manifold = false; f= m.face.end(); --f; j=3; } } } if (!Manifold) { fprintf(index, "

Manifold: NO

"); printf( "\t Manifold: NO\n"); } else { fprintf(index, "

Manifold: YES

"); printf( "\t Manifold: YES\n "); } // COUNT EDGES MyMesh::FaceIterator fi; int count_e = 0; bool counted=false; for(fi=m.face.begin();fi!=m.face.end();++fi) (*fi).ClearS(); for(fi=m.face.begin();fi!=m.face.end();++fi) { (*fi).SetS(); count_e +=3; for(int i=0; i<3; ++i) { if (IsManifold(*fi,i)) { if((*fi).FFp(i)->IsS()) count_e--; } else { hei.Set(&(*fi), i , fi->V(i)); he=hei; he.NextF(); while (he.f!=hei.f) { if (he.f->IsS()) { counted=true; break; } else { he.NextF(); } } if (counted) { count_e--; counted=false; } } } } fprintf(index, "

Number of edges: %d

\n", count_e); printf("\t Number of edges: %d \n", count_e); // DA QUI IN POI!!! // DEGENERATED FACES int count_fd = 0; for(fi=m.face.begin(); fi!=m.face.end();++fi) if((*fi).Area() == 0) count_fd++; fprintf(index, "

Number of degenerated faces: %d

\n", count_fd); printf("\t Number of degenerated faces: %d \n", count_fd); // UNREFERENCED VERTEX int count_uv = 0; MyMesh::VertexIterator v; for(v=m.vert.begin();v!=m.vert.end();++v) (*v).ClearV(); for(f=m.face.begin();f!=m.face.end();++f) for(j=0;j<3;++j) (*f).V(j)->SetV(); for(v=m.vert.begin();v!=m.vert.end();++v) if( !(*v).IsV() ) ++count_uv; fprintf(index,"

Number of unreferenced vertices: %d

\n",count_uv); printf("\t Number of unreferenced vertices: %d\n",count_uv); // HOLES COUNT for(f=m.face.begin();f!=m.face.end();++f) (*f).ClearS(); g=m.face.begin(); f=g; int BEdges=0; int numholes=0; if (Manifold) { for(f=g;f!=m.face.end();++f) { if(!(*f).IsS()) { for(j=0;j<3;j++) { if ((*f).IsBorder(j)) { BEdges++; if(!(IsManifold(*f,j))) { (*f).SetS(); hei.Set(&(*f),j,f->V(j)); he=hei; do { he.NextB(); he.f->SetS(); // BEdges++; } while (he.f!=hei.f); //BEdges--; numholes++; } } } } } } else { for(f=g;f!=m.face.end();++f) { for(j=0;j<3;j++) { if ((*f).IsBorder(j)) { BEdges++; } } } } if (Manifold) { fprintf(index, "

Number of holes: %d

\n

Number of border edges: %d

", numholes, BEdges); printf("\t Number of holes: %d \n", numholes, BEdges); printf("\t Number of border edges: %d\n", numholes, BEdges); } else { fprintf(index, "

Number of border edges: %d

", BEdges); printf("\t Number of border edges: %d\n", BEdges); } // Mesh Volume float vol = m.Volume(); int nuh = numholes; if((m.Volume()>0.)&&(Manifold)&&(numholes==0)) { fprintf(index,"

Volume: %d

\n", m.Volume()); printf("\t Volume: %f \n", m.Volume()); } // CONNECTED COMPONENTS for(f=m.face.begin();f!=m.face.end();++f) (*f).ClearS(); g=m.face.begin(); f=g; int CountComp=0; int CountOrient=0; stack sf; MyMesh::FaceType *l; for(f=m.face.begin();f!=m.face.end();++f) { if (!(*f).IsS()) { (*f).SetS(); sf.push(f); while (!sf.empty()) { g=sf.top(); he.Set(&(*g),0,g->V(0)); sf.pop(); for(j=0;j<3;++j) if( !(*g).IsBorder(j) ) { l=he.f->FFp(j); if( !(*l).IsS() ) { (*l).SetS(); sf.push(l); } } } CountComp++; } } fprintf(index, "

Number of connected components: %d

", CountComp); printf("\t Number of connected components: %d\n", CountComp); if(CountComp ==1) { int eulero; //v-e+f eulero = (m.vn-count_uv)- (count_e+BEdges)+m.fn; if(Manifold) { int genus = (2-eulero)>>1; fprintf(index, "

Genus: %d

\n ", genus); printf( "\t Genus: %d \n", genus); } } // REGULARITY bool Regular=true; bool Semiregular=true; int inc=0; for(v=m.vert.begin();v!=m.vert.end();++v) (*v).ClearS(); for(f=m.face.begin();f!=m.face.end();++f) { for (j=0; j<3; j++) { he.Set(&(*f),j,f->V(j)); if (!(*f).IsBorder(j) && !(*f).IsBorder((j+2)%3) && !f->V(j)->IsS()) { hei=he; inc=1; he.FlipE(); he.NextF(); while (he.f!=hei.f) { he.FlipE(); if (he.IsBorder()) { inc=6; break; } he.NextF(); inc++; } if (inc!=6) Regular=false; if (inc!=6 && inc!=5) Semiregular=false; f->V(j)->SetS(); } else f->V(j)->SetS(); } if (Semiregular==false) break; } if (Regular) { fprintf(index, "

Type of Mesh: REGULAR

"); printf("\t Type of Mesh: REGULAR\n"); } else if (Semiregular) { fprintf(index, "

Type of Mesh: SEMIREGULAR

"); printf("\t Type of Mesh: SEMIREGULAR\n"); } else { fprintf(index, "

Type of Mesh: IRREGULAR

"); printf("\t Type of Mesh: IRREGULAR\n"); } // ORIENTABLE E ORIENTED MESH bool Orientable=true; bool Oriented=true; if (!Manifold) { fprintf(index, "

Orientable Mesh: NO

"); printf( "\t Orientable Mesh: NO\n"); } else { for(f=m.face.begin();f!=m.face.end();++f) { (*f).ClearS(); (*f).ClearUserBit(0); } g=m.face.begin(); f=g; for(f=m.face.begin();f!=m.face.end();++f) { if (!(*f).IsS()) { (*f).SetS(); sf.push(f); while (!sf.empty()) { g=sf.top(); sf.pop(); for(j=0;j<3;++j) { if( !(*g).IsBorder(j) ) { he.Set(&(*g),0,g->V(0)); l=he.f->FFp(j); he.Set(&(*g),j,g->V(j)); hei.Set(he.f->FFp(j),he.f->FFi(j), (he.f->FFp(j))->V(he.f->FFi(j))); if( !(*g).IsUserBit(0) ) { if (he.v!=hei.v) // bene { if ((*l).IsS() && (*l).IsUserBit(0)) { Orientable=false; break; } else if (!(*l).IsS()) { (*l).SetS(); sf.push(l); } } else if (!(*l).IsS()) { Oriented=false; (*l).SetS(); (*l).SetUserBit(0); sf.push(l); } else if ((*l).IsS() && !(*l).IsUserBit(0)) { Orientable=false; break; } } else if (he.v==hei.v) // bene { if ((*l).IsS() && (*l).IsUserBit(0)) { Orientable=false; break; } else if (!(*l).IsS()) { (*l).SetS(); sf.push(l); } } else if (!(*l).IsS()) { Oriented=false; (*l).SetS(); (*l).SetUserBit(0); sf.push(l); } else if ((*l).IsS() && !(*l).IsUserBit(0)) { Orientable=false; break; } } } } } if (!Orientable) break; } if (Orientable) { fprintf(index, "

Orientable Mesh: YES

"); printf( "\t Orientable Mesh: YES\n"); } else { fprintf(index, "

Orientable Mesh: NO

"); printf( "\t Orientable Mesh: NO\n"); } } if (Oriented && Manifold) { fprintf(index, "

Oriented Mesh: YES

"); printf( "\t Oriented Mesh: YES\n"); } else { fprintf(index, "

Oriented Mesh: NO

"); printf( "\t Oriented Mesh: NO\n"); } int dv = DuplicateVertex(m); if(dv>0) { fprintf(index, "

Duplicated vertices: %d

", dv); printf( "\t Duplicated vertices: %d\n",dv); } else { fprintf(index, "

Duplicated vertices: NO

"); printf( "\t Duplicated vertices: NO\n"); } // SELF INTERSECTION if (m.fn<300000) { bool SelfInt=false; for(f=m.face.begin();f!=m.face.end();++f) { for(g=++f , f--;g!=m.face.end();++g) { if ((*f).FFp(0)!=&(*g) && (*f).FFp(1)!=&(*g) && (*f).FFp(2)!=&(*g) && f->V(0)!=g->V(0) && f->V(0)!=g->V(1) && f->V(0)!=g->V(2) && f->V(1)!=g->V(0) && f->V(1)!=g->V(1) && f->V(1)!=g->V(2) && f->V(2)!=g->V(0) && f->V(2)!=g->V(1) && f->V(2)!=g->V(2)) { if (NoDivTriTriIsect(f->V(0)->P(), f->V(1)->P(), f->V(2)->P(),g->V(0)->P(), g->V(1)->P(), g->V(2)->P()) ) SelfInt=true; } } if (SelfInt) break; } if (SelfInt) { fprintf(index, "

Self Intersection: YES

"); printf( "\t Self Intersection: YES\n"); } else { fprintf(index, "

Self Intersection: NO

"); printf( "\t Self Intersection: NO\n"); } } fclose(index); } meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/history.txt0000644000175000017500000000330611517500600022055 0ustar gladkgladk VCGLib http://vcg.sf.net o o Visual and Computer Graphics Library o o _ O _ Copyright(C) 2005-2006 \/)\/ Visual Computing Lab http://vcg.isti.cnr.it /\/| ISTI - Italian National Research Council | \ TriMeshInfo 1.22 2006/10/30 All rights reserved. 2006/10/30 Release 1.22 Better support of off and obj files. Now it can parse also slightly incorrect files reporting warnings without blocking. 2006/03/27 Release 1.21 Now trimeshinfo support OFF,STL,OBJ and PLY format Added normal, color and texture information Fix mesh info data initialization 2005/12/21 Release 1.2 Fix orientability and genus computation. Re-design output (add HTML info support). 2005/09/28 Release 1.02 Added possibility of saving File in OFF format Changed main file name from main.cpp intp trimeshinfo.cpp to uniform with other projects. Fixed some errors in counting edges and holes routines. 2005/2/16 Release 1.01 Added new functionality to the application: - Volume (Computed only for Closed Manifold Datasets) - Color (Computed only if the information is embedded in the model) - Genus (Computed only for Manifold Datasets) - Number of Duplicated Vertices - Self-Intersection (Currently computed only for Datasets with less than 3M faces) Modified output layout. 2005/01/19 Release 1.0 First working version. meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo.pro0000644000175000017500000000025711517500600022666 0ustar gladkgladk TARGET = trimeshinfo LIBPATH += DEPENDPATH += . INCLUDEPATH += . ../.. CONFIG += console stl TEMPLATE = app HEADERS += SOURCES += trimeshinfo.cpp ../../wrap/ply/plylib.cppmeshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/InstancesNode.h0000644000175000017500000000260511517500600022522 0ustar gladkgladk #include #include #include #include "Node.h" class InstanceNode: public Node { public: InstanceNode(void){node_type = INSTANCE_NODE; id = "empty"; type= "empty";}; char* id; char* type; int node_type; OwnSlotsNode own_slots; void addOwnSlots(OwnSlotsNode* own_slots); virtual void printNode(); virtual int qualifyNode(); }; void InstanceNode::addOwnSlots(OwnSlotsNode* sn) { own_slots.addOwnSlot(&sn->own_slot); } void InstanceNode::printNode() { cout<<"InstanceNode: Node node_type is "<addOwnSlots(&in->own_slots); } void InstancesNode::printNode() { cout<<"InstancesNode: Node type is "<::iterator it; for(it = instances.Sons.begin(); it!=instances.Sons.end(); ++it) (*it)->printNode(); } int InstancesNode::qualifyNode() {return node_type;} meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/readme.txt0000644000175000017500000000732611517500600021617 0ustar gladkgladk VCGLib http://vcg.sf.net o o Visual and Computer Graphics Library o o _ O _ Copyright(C) 2004-2006 \/)\/ Visual Computing Lab http://vcg.isti.cnr.it /\/| ISTI - Italian National Research Council | \ TriMeshInfo 1.22 2006/10/30 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. --- Synopsis --- TriMeshInfo is a tool designed to inspect 3D models and retrieve all the topological related information. It can be used to automate the process of decoding 3D mesh inherent properties and ease data classification and retrieval. For each analyzed dataset the following information are extracted: * Number of Vertices * Number of Faces * Number of Edges * Number of Connected Components * Number of Boundaries * Number of Isolated Vertices (i.e. Unreferenced) * Number of Duplicated vertices (duplicated vertices are referenced vertices which have the same positon in the space) * Manifold * Genus (computed only for Manifold Datasets) * Self-Intersection (currently computed only for Datasets with less than 3M faces) * Orientability * Orientation * Regularity (We consider REGULAR those meshes that have 6 incident edges for each internal vertex, and 4 incident edges for each vertex on the boundary. In all other cases we consider the mesh irregular.) * Volume * Attribute present on mesh (colors, texture coords etc); The application has no graphical interface but works as the "Metro" tool on command line. TriMeshInfo is written in C++ and makes use of the VCG library. The tool supports the following file formats: - PLY (http://vcg.sourceforge.net/img/wiki_up/plyformat.pdf) - OFF (http://www.geomview.org/docs/html/geomview_41.html#SEC44) - STL (http://astronomy.swin.edu.au/~pbourke/dataformats/stl/) - OBJ (http://www.eg-models.de/formats/Format_Obj.html) --- Command-line Reference --- Usage: TriMeshInfo [options] Valid options are the following: -q Quiet (disable verbose mode that is enabled by default) -x Enable XML output -h Enable HTML output -s Save the clean mesh The HTML output creates in the directory where TriMeshInfo is launched a file called "result.html". This file contains an hmtl table with the retrieved mesh information. If this file is just present in the working directory the output of the TriMeshInfo is added to the existing table. In this way it is possible to summarize the results obtained from several meshes. If you choose to save the "clean" mesh, the mesh without its unreferenced vertices and with the duplicated vertices merged is saved. meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/ClassesNode.h0000644000175000017500000000377211517500600022176 0ustar gladkgladk#include #include #include #include "Node.h" using namespace std; class OwnSlotsNode: public Node { public: OwnSlotsNode(void){node_type = OWNSLOTS_NODE;}; int node_type; NodeGroup own_slot; virtual void printNode(); virtual int qualifyNode(); void addOwnSlot(NodeGroup* ng); void addOwnSlot(OwnSlotNode* os); }; void OwnSlotsNode::addOwnSlot(NodeGroup* ng) { list::iterator it; for(it = ng->Sons.begin(); it!=ng->Sons.end(); ++it) own_slot.addNode(*it); } void OwnSlotsNode::addOwnSlot(OwnSlotNode* os) { //OwnSlotNode* osn = new OwnSlotNode; // own_slots.Sons.push_back(new OwnSlotNode); own_slot.addNode(os); } void OwnSlotsNode::printNode() { cout<<"OwnSlotsNode: Node type is "<::iterator it; for(it = own_slot.Sons.begin(); it!=own_slot.Sons.end(); ++it) (*it)->printNode(); } int OwnSlotsNode::qualifyNode() {return node_type;} class ClassNode: public Node { public: ClassNode(void){node_type = CLASS_NODE;}; int node_type; OwnSlotsNode own_slots; void addOwnSlots(OwnSlotsNode* own_slots); virtual void printNode(); virtual int qualifyNode(); }; void ClassNode::addOwnSlots(OwnSlotsNode* sn) { own_slots.addOwnSlot(&sn->own_slot); } void ClassNode::printNode() { cout<<"ClassNode: Node type is "<addOwnSlots(&cn->own_slots); } void ClassesNode::printNode() { cout<<"ClassesNode: Node type is "<::iterator it; for(it = classn.Sons.begin(); it!=classn.Sons.end(); ++it) (*it)->printNode(); } int ClassesNode::qualifyNode() {return node_type;} meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/Node.h0000644000175000017500000000263211517500600020652 0ustar gladkgladk #ifndef NODE_H #define NODE_H #include using namespace std; class Node { public: //int node_type; virtual ~Node(void){}; virtual void printNode()=0; virtual int qualifyNode()=0; }; class NodeGroup :public Node { public: virtual ~NodeGroup(); typedef list::iterator iterator; list Sons; virtual void addNode(Node* nd); virtual void printNode(); virtual int qualifyNode(); }; NodeGroup::~NodeGroup() //distruttore: disalloca tutti i figli { //for(iterator i=Sons.begin();i!=Sons.end();++i) // delete (*i); } void NodeGroup::addNode(Node* nd) { Sons.push_back(nd); } void NodeGroup::printNode() {} int NodeGroup::qualifyNode() {return 0;} const int MAIN_NODE= 0; const int SLOTS_NODE= 1; const int SLOT_NODE= 2; const int OWNSLOT_NODE= 3; const int ENTRY_NODE= 4; const int VALUE_NODE= 5; const int CLASSES_NODE= 6; const int CLASS_NODE= 7; const int OWNSLOTS_NODE= 8; const int INSTANCES_NODE= 9; const int INSTANCE_NODE= 10; enum values {VALUE_INTEGER, VALUE_FLOAT, VALUE_BOOL, VALUE_STRING}; //#define MAIN_NODE 0; //#define SLOTS_NODE 1; //#define SLOT_NODE 2; //#define OWNSLOT_NODE 3; //#define ENTRY_NODE 4; //#define VALUE_NODE 5; // //#define CLASSES_NODE 6; //#define CLASS_NODE 7; //#define OWNSLOTS_NODE 8; // //#define INSTANCES_NODE 9; //#define INSTANCE_NODE 10; #endif meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.02/0000755000175000017500000000000012227522351022447 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.02/trimeshinfosample/0000755000175000017500000000000012227522351026200 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.02/trimeshinfosample/readme.txt0000644000175000017500000000131411517500577030204 0ustar gladkgladkThis directory contains six 3d models that can be used to test trimeshinfo. The models represent a toroidal knot at two different level of details: - knot_orig.ply 12800 vertexes, 25600 triangles: the original high resolution mesh - knot_subsampled.ply 800 vertexes, 1600 triangles: a low res model obtained by simple uniform subsampling - knot_vcg_simplified.ply 800 vertexes, 1600 triangles: a low res model obtained by our library simplification code a low resolution model of the Kleine bottle: - kleine.ply 255 vertexes, 520 triangles two low resolution models of the moebius strip: - moebius.ply 80 vertexes, 160 triangles - moebius_big.ply 320 vertexes, 480 triangles meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.02/trimeshinfo1.02/0000755000175000017500000000000012227522351025277 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo1.02/trimeshinfo1.02/readme.txt0000644000175000017500000000542011517500572027300 0ustar gladkgladk VCGLib http://vcg.sf.net o o Visual and Computer Graphics Library o o _ O _ Copyright(C) 2004-2005 \/)\/ Visual Computing Lab http://vcg.isti.cnr.it /\/| ISTI - Italian National Research Council | \ TriMeshInfo 1.0 21/09/2004 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. --- Synopsis --- TriMeshInfo is a tool designed to inspect 3D models and retrieve all the topological related information. It can be used to automate the process of decoding 3D mesh inherent properties and ease data classification and retrieval. For each analyzed dataset the following information are extracted: * Number of Vertices (Unreferenced vertices are listed separately) * Number of Faces * Number of Edges * Number of Connected Components * Number of Boundaries * Number of Isolated Vertices (i.e. Unreferenced) * Manifold * Genus (Computed only for Manifold Datasets) * Self-Intersection (Currently computed only for Datasets with less than 3M faces) * Orientability * Orientation * Regularity (We consider as regular those meshes generated through regular subdivision. Each non boundary vertex of a regular mesh has 6 incident edges, if there are only 5 incident edges the mesh is said to be semi-regular, irregular in all other cases) The application has no graphical interface but works as the "Metro" tool on command line. TriMeshInfo is written in C++ and makes use of the VCL library. The tool supports two file formats ply (as described in the following document http://vcg.sourceforge.net/img/wiki_up/plyformat.pdf) and off (as described in http://www.geomview.org/docs/html/geomview_41.html#SEC44) . meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/XMLTree.h0000644000175000017500000001714511517500600021252 0ustar gladkgladk #include #include #include #include #include #include "SlotsNode.h" #include "ClassesNode.h" #include "InstancesNode.h" using namespace std; static char* XML_SCHEMA_NAME = "protegekb"; class FacetNode: public Node { virtual void printNode(); virtual int qualifyNode(); }; class FacetsNode: public Node { NodeGroup facets; virtual void printNode(); virtual int qualifyNode(); }; class MainNode: public Node { public: MainNode(void){node_type = MAIN_NODE;}; int node_type; list > headers; void addHeaders(const char* str, const char* val); virtual void printNode(); virtual int qualifyNode(); }; void MainNode::addHeaders(const char* str, const char*val) { headers.push_back(pair(str,val)); } void MainNode::printNode() { cout << "MainNode: node_type is " << node_type << "\n"; list >::iterator it; for(it = headers.begin(); it!= headers.end(); ++it) { cout << "MainNode: First element is " << it->first << "\n"; cout << "MainNode: Second element is " << it->second << "\n"; } } int MainNode::qualifyNode() {return node_type;} class XMLTree { private: static const char *DEFAULT_NAME; string filename; bool verbose; public: XMLTree(void){verbose = false;} ~XMLTree(void){} NodeGroup root; NodeGroup ng; SlotNode sn; // methods void setName(const char *name); void setVerboseMode(bool flag); void initializeMain(); void finalizeMain(); void addHeaders(const char* str, const char*val); void addSlots(SlotNode* sn); //void addFacets(); void addClasses(ClassNode* cn); void addInstances(InstanceNode* in); void addNode(const char* s, int value_type, const char* name); void printXMLTree(); }; const char * XMLTree::DEFAULT_NAME = "XmlTree.xml"; void XMLTree::setName(const char *name) { filename = name; } void XMLTree::setVerboseMode(bool flag) { verbose = flag; } void XMLTree::initializeMain() { MainNode* mn = new MainNode; mn->headers.push_back(pair("protegekb", "")); char* s1 = "http://www.w3.org/2001/XMLSchema-instance"; char* s2 = new char[100]; sprintf(s2,"\"%s\"",s1); mn->addHeaders(" xmlns:xsi=", s2); s1 = "http://protege.stanford.edu/plugins/xmlbackend/protege_xml_backend.xsd"; sprintf(s2,"\"%s\"",s1); mn->addHeaders(" xsi:noNamespaceSchemaLocation=", s2); root.Sons.push_back(mn); } void XMLTree::finalizeMain() { addSlots(&sn); OwnSlotsNode* ossn = new OwnSlotsNode; ossn->addOwnSlot(&ng); ClassNode* cn = new ClassNode; cn->addOwnSlots(ossn); addClasses(cn); InstanceNode* in = new InstanceNode; in->addOwnSlots(ossn); addInstances(in); MainNode* mn = new MainNode; mn->headers.push_back(pair("/",XML_SCHEMA_NAME)); root.Sons.push_back(mn); } void XMLTree::addHeaders(const char* str, const char*val) { MainNode* mn = dynamic_cast(root.Sons.front()); mn->headers.push_back(pair(str,val)); } void XMLTree::addSlots(SlotNode* sn) { SlotsNode* sn0 = new SlotsNode; // 1 solo sn0->addSlot(sn); root.Sons.push_back(sn0); } void XMLTree::addClasses(ClassNode* cn) { ClassesNode* cn0 = new ClassesNode; // 1 solo cn0->addClass(cn); root.Sons.push_back(cn0); } void XMLTree::addNode(const char* s, int value_type, const char* name) { ValueNode* vn = new ValueNode; EntryNode* en = new EntryNode; OwnSlotNode* osn = new OwnSlotNode; switch(value_type) { case VALUE_INTEGER: en->type = "Integer"; break; case VALUE_FLOAT: en->type = "Float"; break; case VALUE_BOOL: en->type = "Bool"; break; case VALUE_STRING: en->type = "String"; break; } vn->setValue(s); en->addValue(*vn); osn->setName(name); osn->addEntry(*en); sn.addOwnSlot(osn); ng.addNode(osn); } void XMLTree::addInstances(InstanceNode* in) { InstancesNode* in0 = new InstancesNode; // 1 solo in0->addInstance(in); root.Sons.push_back(in0); } void XMLTree::printXMLTree() { FILE *fp; if (filename.empty()) fp = fopen(DEFAULT_NAME, "w"); else fp = fopen(filename.c_str(), "w"); list::iterator it; list::iterator it2; list::iterator it3; list >::iterator lit; MainNode* mn; SlotsNode* sns; SlotNode* sn; OwnSlotNode* osn; ClassesNode* csn; ClassNode* cn; InstancesNode* isn; InstanceNode* in; int nn = 0; for(it = root.Sons.begin(); it!=root.Sons.end(); ++it) { if (verbose) { cout<<"Creating Node #"<< nn<<"\n"; cout<<"Node Type is "<< (*it)->qualifyNode()<<"\n"; } switch((*it)->qualifyNode()) { // MAIN NODE case MAIN_NODE: mn = dynamic_cast(*it); fprintf(fp,"<"); for(lit = mn->headers.begin(); lit!= mn->headers.end(); ++lit) fprintf(fp,"%s%s", lit->first,lit->second ); fprintf(fp,"> \n"); break; // SLOTS case SLOTS_NODE: sns = dynamic_cast(*it); fprintf(fp,"\t\n"); for(it2 = sns->slot.Sons.begin(); it2!=sns->slot.Sons.end(); ++it2) { sn = dynamic_cast(*it2); fprintf(fp,"\t\t\n"); for(it3 = sn->own_slot.Sons.begin(); it3!=sn->own_slot.Sons.end(); ++it3) { osn = dynamic_cast(*it3); fprintf(fp,"\t\t\t\n",osn->name); fprintf(fp,"\t\t\t\t\n",osn->entry.type); fprintf(fp,"\t\t\t\t\t%s", osn->entry.value.value.c_str()); fprintf(fp,"\n"); fprintf(fp,"\t\t\t\t\n"); fprintf(fp,"\t\t\t\n"); } fprintf(fp,"\t\t\n"); } fprintf(fp,"\t\n"); break; // CLASSES case CLASSES_NODE: csn = dynamic_cast(*it); fprintf(fp,"\t\n"); for(it2 = csn->classn.Sons.begin(); it2!=csn->classn.Sons.end(); ++it2) { cn = dynamic_cast(*it2); fprintf(fp,"\t\t\n"); fprintf(fp,"\t\t\t\n"); for(it3 = cn->own_slots.own_slot.Sons.begin(); it3!=cn->own_slots.own_slot.Sons.end(); ++it3) { osn = dynamic_cast(*it3); fprintf(fp,"\t\t\t\t\n",osn->name); fprintf(fp,"\t\t\t\t\t\n",osn->entry.type); fprintf(fp,"\t\t\t\t\t\t%s", osn->entry.value.value.c_str()); fprintf(fp,"\n"); fprintf(fp,"\t\t\t\t\t\n"); fprintf(fp,"\t\t\t\t\n"); } fprintf(fp,"\t\t\t\n"); fprintf(fp,"\t\t\n"); } fprintf(fp,"\t\n"); break; // INSTANCES case INSTANCES_NODE: isn = dynamic_cast(*it); fprintf(fp,"\t\n"); for(it2 = isn->instances.Sons.begin(); it2!=isn->instances.Sons.end(); ++it2) { in = dynamic_cast(*it2); fprintf(fp,"\t\t\n"); fprintf(fp,"\t\t\t\n"); fprintf(fp,"\t\t\t%s\n", in->id); fprintf(fp,"\t\t\t\n"); fprintf(fp,"\t\t\t\n"); fprintf(fp,"\t\t\t%s\n", in->type); fprintf(fp,"\t\t\t\n"); fprintf(fp,"\t\t\t\n"); for(it3 = in->own_slots.own_slot.Sons.begin(); it3!=in->own_slots.own_slot.Sons.end(); ++it3) { osn = dynamic_cast(*it3); fprintf(fp,"\t\t\t\t\n",osn->name); fprintf(fp,"\t\t\t\t\t\n",osn->entry.type); fprintf(fp,"\t\t\t\t\t\t%s", osn->entry.value.value.c_str()); fprintf(fp,"\n"); fprintf(fp,"\t\t\t\t\t\n"); fprintf(fp,"\t\t\t\t\n"); } fprintf(fp,"\t\t\t\n"); fprintf(fp,"\t\t\n"); } fprintf(fp,"\t\n"); break; } ++nn; } fclose(fp); } meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/SlotsNode.h0000644000175000017500000000601711517500600021700 0ustar gladkgladk #include #include #include #include "Node.h" using namespace std; class ValueNode: public Node { public: ValueNode(void){node_type = VALUE_NODE;value = "empty";}; int node_type; string value; //tra due tag virtual void printNode(); virtual int qualifyNode(); void setValue(ValueNode vn){value = vn.value;}; void setValue(const char* cvn){value = cvn;}; }; void ValueNode::printNode() { cout<<"ValueNode: Node type is "<::iterator it; for(it = own_slot.Sons.begin(); it!=own_slot.Sons.end(); ++it) (*it)->printNode(); } int SlotNode::qualifyNode() {return node_type;} class SlotsNode: public Node { public: SlotsNode(void){node_type = SLOTS_NODE;}; int node_type; NodeGroup slot; void addSlot(SlotNode* sn); virtual void printNode(); virtual int qualifyNode(); }; void SlotsNode::addSlot(SlotNode* sn) { slot.Sons.push_back(new SlotNode); SlotNode* slp = (SlotNode*) slot.Sons.front(); list::iterator it; for(it = sn->own_slot.Sons.begin(); it!=sn->own_slot.Sons.end(); ++it) slp->addOwnSlot(((OwnSlotNode*)(*it))); } void SlotsNode::printNode() { cout<<"SlotsNode: Node type is "<::iterator it; for(it = slot.Sons.begin(); it!=slot.Sons.end(); ++it) (*it)->printNode(); } int SlotsNode::qualifyNode() {return node_type;} meshlab-1.3.2+dfsg1/vcglib/apps/trimeshinfo/trimeshinfo.cpp0000644000175000017500000005443211573077430022670 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2005 \/)\/ * * 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.41 2007/03/08 22:49:35 cignoni Changed the include order and the order in which cleaning filters are applied. Revision 1.40 2006/05/16 21:55:28 cignoni Updated to the new remove zero area syntax Revision 1.39 2006/03/29 09:27:07 cignoni Added managemnt of non critical errors Revision 1.38 2006/03/29 08:17:56 corsini fix typo Revision 1.37 2006/03/27 07:15:59 cignoni Added LoadMask Revision 1.36 2006/02/28 14:54:10 corsini Fix load mask initialization Revision 1.35 2006/02/09 16:12:27 corsini Add normal, color, texture information Revision 1.34 2006/02/06 12:59:12 corsini Fix mesh info structure initialization Revision 1.33 2006/01/27 14:18:07 corsini fix boolean entry type Revision 1.32 2006/01/27 14:17:10 corsini remove junk code Revision 1.31 2006/01/27 13:35:51 corsini fix signed/unsigned mismatch Revision 1.30 2006/01/26 16:29:21 corsini fix typo Revision 1.29 2005/12/29 12:27:35 cignoni Splitted IsComplexManifold in IsTwoManifoldFace and IsTwoManifoldVertex Revision 1.28 2005/12/21 14:11:59 corsini Out the number of self intersection Revision 1.27 2005/12/21 13:26:58 corsini Re-add save xml feature Revision 1.26 2005/12/21 13:10:10 corsini Move duplicated vertices routine Modify genus computation call Revision 1.25 2005/12/20 14:44:10 corsini Modify html table Revision 1.24 2005/12/20 13:29:41 corsini Remove unuseful Clear function Revision 1.23 2005/12/19 15:00:53 corsini Disable xml output temporarily Revision 1.22 2005/12/19 11:35:13 corsini Add html output support Revision 1.21 2005/12/16 11:16:36 corsini Add manifold check to some properties Revision 1.20 2005/12/15 11:20:00 corsini Add vertex-face topology Revision 1.19 2005/12/14 14:05:37 corsini Adjust comments Revision 1.18 2005/12/14 12:15:37 corsini Re-add clean mesh saving feature Revision 1.17 2005/12/13 15:46:30 corsini Restructuring code Revision 1.16 2005/12/12 12:09:08 cignoni Changed names of clean function and tested inertia.h Revision 1.15 2005/12/12 11:29:21 corsini Minor changes Revision 1.14 2005/12/12 10:48:16 corsini Fix indentation Revision 1.13 2005/11/17 00:42:03 cignoni Changed include order removed clean::initialize Revision 1.12 2005/11/16 16:45:51 rita_borgo Minor changes Revision 1.11 2005/11/16 15:59:46 cignoni Changed name of the component from to Revision 1.10 2005/11/14 09:21:07 cignoni Heavily restructured the code of Trimeshinfo. Now divided the collecting part from the reporting one (xml and ascii) Revision 1.9 2005/11/04 15:37:57 rita_borgo Removed Debug option Revision 1.8 2005/10/11 16:03:40 rita_borgo Moved all the main functions inside clean.h Revision 1.7 2005/09/30 15:48:46 rita_borgo Fixed manifold Test Revision 1.6 2005/09/30 14:13:01 rita_borgo Problem: Text not aligned Revision 1.5 2005/09/30 13:29:40 rita_borgo Fixed Manifold Test Revision 1.4 2005/09/29 14:48:15 rita_borgo Fixed code related to creation of the XML file Revision 1.3 2005/09/28 13:57:09 rita_borgo Fixed some printout not alligned Revision 1.2 2005/09/28 10:46:04 rita_borgo Added possibility of saving File in OFF format Revision 1.1 2005/09/20 10:15:27 rita_borgo Changed file name to uniform with other solution projects, before was main.cpp Revision 1.8 2005/02/15 12:26:06 rita_borgo Minor changes to self-intersection Revision 1.7 2005/02/07 15:44:31 rita_borgo Fixed Color and Volume Revision 1.6 2005/02/01 17:37:53 rita_borgo Fixed Volume and Color Revision 1.5 2005/01/18 16:33:12 rita_borgo Added OFF file Option Revision 1.4 2005/01/17 18:19:00 rita_borgo Added new routines. Self-intersection first release Revision 1.2 2005/01/03 16:13:09 rita_borgo Added Standard comments ****************************************************************************/ // Standard headers #include #include #include #include #include using namespace std; // VCG headers #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "XMLTree.h" #include #include "defs.h" using namespace vcg; class CVertex; class CFace; struct MyTypes: public UsedTypes< Use::AsVertexType,Use::AsFaceType>{}; class CVertex : public Vertex< MyTypes, vertex::VFAdj, vertex::Coord3f,vertex::BitFlags, vertex::Normal3f > {}; class CFace : public Face< MyTypes, face::FFAdj, face::VFAdj, face::VertexRef, face::Normal3f, face::BitFlags, face::Mark > {}; class CMesh : public vcg::tri::TriMesh< vector, vector > {}; typedef CMesh::VertexPointer VertexPointer; typedef CMesh::VertexIterator VertexIterator; typedef Point3 Point3x; typedef vector Hole; typedef CMesh::VertexPointer VertexPointer; typedef CMesh::VertexIterator VertexIterator; typedef CMesh::FaceContainer FaceContainer; typedef CMesh::ScalarType ScalarType; struct MeshInfo { string FileName; bool hasVNormal; bool hasFNormal; bool hasVColor; bool hasFColor; bool hasTexture; int vn,fn; bool VManifold; bool FManifold; int count_e,boundary_e,count_fd,count_uv,numholes; int BEdges; float Volume; int numcomponents,Genus; bool Regular,Semiregular; bool Orientable,Oriented; int dv; bool SelfIntersect; std::vector intersections; }; static const int HTML_LINES = 31; static const char * HTML_TABLE[HTML_LINES]= { "", " ", " ", " description.html", " ", " ", " ", "

TriMeshInfo V.1.2 - Results

", "

", " ", " ", " ", " Name", " Vertices", " Faces", " Edges", " Holes/
Boundaries", " Connected
Components", " Isolated
Vertices", " Duplicated
Vertices", " Self
Interesection", " Manifold", " Orientable/
Oriented", " Genus", " ", " ", " ", " ", "" }; int OpenMesh(const char *filename, CMesh &m) { printf(" Mesh loading..."); int mask = 0; tri::io::Importer::LoadMask(filename,mask); int err = tri::io::Importer::Open(m, filename); if (err) { if(tri::io::Importer::ErrorCritical(err)) { printf("\n Error during loading %s: '%s'\n",filename, tri::io::Importer::ErrorMsg(err)); exit(-1); } else { printf("\n Non Critical Troubles during loading %s: '%s'\n",filename, tri::io::Importer::ErrorMsg(err)); } } else printf(" done.\n\n"); return mask; } void initMeshInfo(MeshInfo &mi) { mi.vn = 0; mi.fn = 0; mi.hasVColor = false; mi.hasFColor = false; mi.hasFNormal = false; mi.hasVNormal = false; mi.hasTexture = false; mi.VManifold = false; mi.FManifold = false; mi.count_e = 0; mi.boundary_e = 0; mi.count_fd = 0; mi.count_uv = 0; mi.numholes = 0; mi.BEdges = 0; mi.Volume = 0; mi.numcomponents = 0; mi.Genus = 0; mi.Regular = false; mi.Semiregular = false; mi.Orientable = false; mi.Oriented = false; mi.dv = 0; mi.SelfIntersect = false; // mi.FileName has a constructor // mi.intersections has a constructor } void PrintMeshInfo(MeshInfo &mi) { printf(" *** Mesh information ***\n\n"); printf(" Mesh: '%s' \n", mi.FileName.c_str()); printf(" Number of vertices: %d \n", mi.vn); printf(" Number of faces: %d \n", mi.fn); printf(" Number of edges: %d \n", mi.count_e); printf(" Number of internal edges: %d \n", mi.count_e-mi.boundary_e); printf(" Number of boundary edges: %i \n", mi.boundary_e); printf(" Number of degenerated faces: %d\n", mi.count_fd); printf(" Number of unreferenced vertices: %d\n",mi.count_uv); printf(" Number of duplicated vertices found: %d\n", mi.dv); printf(" Number of holes/boundaries: %d \n", mi.numholes); if (mi.hasVNormal) printf(" Has Per-Vertex Normal: YES\n"); else printf(" Has Per-Vertex Normal: NO\n"); if (mi.hasFNormal) printf(" Has Per-Face Normal: YES\n"); else printf(" Has Per-Face Normal: NO\n"); if (mi.hasVColor) printf(" Has Per-Vertex Color: YES\n"); else printf(" Has Per-Vertex Color: NO\n"); if (mi.hasFColor) printf(" Has Per-Face Color: YES\n"); else printf(" Has Per-Face Color: NO\n"); if (mi.hasTexture) printf(" Has Texture information: YES\n"); else printf(" Has Texture information: NO\n"); if ((mi.VManifold && mi.FManifold )&&(mi.Oriented)&&(!mi.numholes)) printf(" Volume: %f \n", mi.Volume); else printf(" Volume: UNDEFINED (a closed oriented manifold is required)\n"); printf(" Number of connected components: %d\n", mi.numcomponents); // Orientation if (!mi.VManifold && mi.FManifold) { printf(" Orientable Mesh: NO\n"); printf(" Oriented Mesh: NO\n"); } else { if (mi.Orientable) printf(" Orientable Mesh: YES\n"); else printf(" Orientable Mesh: NO\n"); if (mi.Oriented) printf(" Oriented Mesh: YES\n"); else printf(" Oriented Mesh: NO\n"); } // Manifold if (mi.VManifold && mi.FManifold ) printf(" Manifold: YES\n"); else printf(" Manifold: NO\n"); // Genus if (mi.VManifold && mi.FManifold) printf(" Genus: %d \n", mi.Genus); else printf(" Genus: N/A \n"); // Mesh Type if (mi.Regular) printf(" Mesh Type: REGULAR\n"); else if (mi.Semiregular) printf(" Mesh Type: SEMIREGULAR\n"); else printf(" Mesh Type: IRREGULAR\n"); // Further details if (mi.SelfIntersect) printf(" Self Intersection: %d\n", mi.intersections.size()); else printf(" Self Intersection: NONE.\n"); } void SaveXMLInfo(MeshInfo &mi) { XMLTree doc; doc.initializeMain(); char s[256]; sprintf(s,"%d",mi.vn); doc.addNode(s, VALUE_INTEGER, "Number of Vertices"); sprintf(s,"%d",mi.fn); doc.addNode(s, VALUE_INTEGER, "Number of Faces"); if(mi.VManifold && mi.FManifold) doc.addNode("false", VALUE_BOOL,"Manifold"); else doc.addNode("true", VALUE_BOOL,"Manifold"); sprintf(s,"%d",mi.count_e); doc.addNode(s, VALUE_INTEGER,"Number of Edges"); sprintf(s,"%d",mi.count_fd); doc.addNode(s, VALUE_INTEGER,"Number of Degenerated Faces"); sprintf(s,"%d",mi.count_uv); doc.addNode(s, VALUE_INTEGER,"Number of unreferenced vertices"); sprintf(s,"%d",mi.numholes); doc.addNode(s, VALUE_INTEGER, "Number of Holes"); sprintf(s,"%d",mi.BEdges); doc.addNode(s, VALUE_INTEGER, "Number of Border Edges"); if (mi.hasVColor) doc.addNode("true", VALUE_BOOL, "Per-Vertex Color Information"); else doc.addNode("false", VALUE_BOOL, "Per-Vertex Color Information"); if (mi.hasFColor) doc.addNode("true", VALUE_BOOL, "Per-Face Color Information"); else doc.addNode("false", VALUE_BOOL, "Per-Face Color Information"); if (mi.hasVNormal) doc.addNode("true", VALUE_BOOL, "Per-Vertex Normal"); else doc.addNode("false", VALUE_BOOL, "Per-Vertex Normal"); if (mi.hasFNormal) doc.addNode("true", VALUE_BOOL, "Per-Face Normal"); else doc.addNode("false", VALUE_BOOL, "Per-Face Normal"); if (mi.hasTexture) doc.addNode("true", VALUE_BOOL, "Texture Information"); else doc.addNode("false", VALUE_BOOL, "Texture Information"); sprintf(s,"%f",mi.Volume); doc.addNode(s, VALUE_FLOAT,"Volume"); sprintf(s,"%d",mi.numcomponents); doc.addNode(s, VALUE_INTEGER,"Number of Connected Components"); sprintf(s,"%d",mi.Genus); doc.addNode(s, VALUE_INTEGER,"Genus"); if (mi.Regular) doc.addNode("REGULAR", VALUE_STRING,"Type of Mesh"); else if (mi.Semiregular) doc.addNode("SEMIREGULAR", VALUE_STRING,"Type of Mesh"); else doc.addNode("IRREGULAR", VALUE_STRING,"Type of Mesh"); if (!mi.VManifold && mi.FManifold) { doc.addNode("NO", VALUE_STRING,"Orientable Mesh"); doc.addNode("NO", VALUE_STRING,"Oriented Mesh"); } else { doc.addNode(mi.Orientable?"Yes":"No", VALUE_STRING,"Orientable Mesh"); doc.addNode(mi.Oriented?"Yes":"No", VALUE_STRING,"Oriented Mesh"); } sprintf(s,"%d",mi.dv); doc.addNode(s, VALUE_INTEGER,"Duplicated Vertices"); doc.addNode(mi.SelfIntersect?"Yes":"No", VALUE_STRING,"Self Intersection"); doc.finalizeMain(); // save xml tree string filename = mi.FileName; int l = static_cast(filename.size()); int index = static_cast(filename.find_first_of('.')); filename.erase(index, l - index); filename.append(".xml"); doc.setName(filename.c_str()); doc.printXMLTree(); } void SaveMeshInfoHtmlTable(fstream &fout, MeshInfo &mi) { fout << " " << std::endl; fout << " " << mi.FileName << "" << std::endl; fout << " " << mi.vn << "" << std::endl; fout << " " << mi.fn << "" << std::endl; fout << " " << mi.count_e << "" << std::endl; if (mi.VManifold && mi.FManifold) fout << " " << mi.numholes << "" << std::endl; else fout << " N/A" << std::endl; fout << " " << mi.numcomponents << "" << std::endl; fout << " " << mi.count_uv << "" << std::endl; fout << " " << mi.dv << "" << std::endl; if (mi.SelfIntersect) fout << " " << static_cast(mi.intersections.size()) << "" << std::endl; else fout << " None" << std::endl; if(mi.VManifold && mi.FManifold) fout << " Yes" << std::endl; else fout << " No" << std::endl; if ((mi.Orientable)&&(mi.Oriented)) fout << " Yes / Yes" << std::endl; else if ((mi.Orientable)&&(!mi.Oriented)) fout << " Yes / No" << std::endl; else if (!mi.Orientable) fout << " No / No" << std::endl; if (mi.VManifold && mi.FManifold) fout << " " << mi.Genus << "" << std::endl; else fout << " N/A" << std::endl; fout << " " << std::endl; } void SaveHtmlInfo(MeshInfo &mi) { char buff[1024]; bool flagInsert = false; ifstream fin; fstream fout; // Try to open fin.open("result.html"); long pos; if (fin.is_open()) { while (!fin.eof()) { pos = fin.tellg(); fin.getline(buff, 1024); string str(buff); if (str == " ") break; } flagInsert = true; } fin.close(); if (flagInsert) fout.open("result.html", ios::in | ios::out); else fout.open("result.html", ios::out); if (!fout.is_open()) { printf("\n Impossible to write the HTML output file.\n"); } else { if (flagInsert) { // Insert the mesh information into an existing table fout.seekp(pos, ios::beg); SaveMeshInfoHtmlTable(fout, mi); for (int i = HTML_LINES - 4; i < HTML_LINES; i++) fout << HTML_TABLE[i] << std::endl; } else { // Create a new table for (int i = 0; i < HTML_LINES - 4; i++) fout << HTML_TABLE[i] << std::endl; SaveMeshInfoHtmlTable(fout, mi); for (int i = HTML_LINES - 4; i < HTML_LINES; i++) fout << HTML_TABLE[i] << std::endl; } } fout.close(); } int main(int argc, char ** argv) { CMesh m; bool saveCleanMeshFlag = false; // Save the clean mesh bool verboseFlag = true; // Verbose mode on/off bool XmlFlag= false; // XML output enabled/disabled bool HtmlFlag = false; // HTML output enabled/disabled string SaveName; MeshInfo mi; initMeshInfo(mi); printf("\n -------------------------------\n" " TriMeshInfo V.1.23 \n" " http://vcg.isti.cnr.it\n" " release date: "__DATE__"\n" " -------------------------------\n\n\n"); // Parsing arguments /////////////////////////////////////////////// if (argc <= 1) { printf(MSG_ERR_N_ARGS); exit(-1); } mi.FileName = argv[1]; int i = 2; while (i < argc) { if (argv[i][0] == '-') { switch(argv[i][1]) { case 'q' : // Quiet mode, disable verbose mode verboseFlag = false; break; case 's': // Save the clean mesh with the name specified saveCleanMeshFlag = true; // Check clean mesh name (minimal check) if (i+1 >= argc) { printf(" Invalid output mesh name.\n\n"); exit(-1); } else if (argv[i+1][0] != '-') SaveName = argv[i+1]; else { printf(" Invalid output mesh name.\n\n"); exit(-1); } i++; break; case 'x' : // Enable XML output XmlFlag = true; break; case 'h' : // Enable HTML output HtmlFlag = true; break; default: printf(MSG_ERR_INVALID_OPTION, argv[i]); exit(0); break; } } i++; }; // Mesh loading ////////////////////////////////////////// int load_mask = OpenMesh(mi.FileName.c_str(), m); if (load_mask & vcg::tri::io::Mask::IOM_VERTNORMAL) mi.hasVNormal = true; else mi.hasVNormal = false; if (load_mask & vcg::tri::io::Mask::IOM_FACENORMAL) mi.hasFNormal = true; else mi.hasFNormal = false; if (load_mask & vcg::tri::io::Mask::IOM_VERTCOLOR) mi.hasVColor = true; else mi.hasVColor = false; if (load_mask & vcg::tri::io::Mask::IOM_FACECOLOR) mi.hasFColor = true; else mi.hasFColor = false; if( (load_mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD) || (load_mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD) ) mi.hasTexture = true; else mi.hasTexture = false; // Mesh processing ////////////////////////////////////////// printf(" Mesh processing...\n\n"); // Number of vertices mi.vn = m.vn; // Number of faces mi.fn = m.fn; // DUPLICATED VERTICES mi.dv = tri::Clean::RemoveDuplicateVertex(m); // DEGENERATED FACES => (faces with area zero) mi.count_fd = tri::Clean::RemoveDegenerateFace(m); mi.count_fd += tri::Clean::RemoveFaceOutOfRangeArea(m,0); // UNREFERENCED VERTEX mi.count_uv = tri::Clean::RemoveUnreferencedVertex(m); // Update topology (face-to-face) tri::UpdateTopology::FaceFace(m); tri::UpdateTopology::VertexFace(m); // IS MANIFOLD? mi.VManifold = tri::Clean::CountNonManifoldVertexFF(m)>0; mi.FManifold = tri::Clean::CountNonManifoldEdgeFF(m)>0; // COUNT EDGES tri::Clean::CountEdges(m, mi.count_e, mi.boundary_e); // HOLES COUNT if(mi.VManifold && mi.FManifold) { mi.numholes = tri::Clean::CountHoles(m); tri::Clean::CountEdges(m, mi.BEdges,mi.numholes); } // CONNECTED COMPONENTS mi.numcomponents = tri::Clean::CountConnectedComponents(m); // ORIENTATION if (mi.VManifold && mi.FManifold) tri::Clean::IsOrientedMesh(m, mi.Oriented, mi.Orientable); else { mi.Oriented = false; mi.Orientable = false; } // Rebuild Vertex-Face topology tri::UpdateTopology::VertexFace(m); // VOLUME (require a closed oriented manifold) if ((mi.VManifold && mi.FManifold)&&(mi.Oriented)&&(!mi.numholes)) { tri::Inertia mm; mm.Compute(m); mi.Volume = mm.Mass(); // the sign of the volume depend on the mesh orientation if (mi.Volume < 0.0) mi.Volume = -mi.Volume; } // GENUS if(mi.VManifold && mi.FManifold) mi.Genus = tri::Clean::MeshGenus(m, mi.numholes, mi.numcomponents, mi.count_e); // REGULARITY if (mi.VManifold && mi.FManifold) tri::Clean::IsRegularMesh(m, mi.Regular, mi.Semiregular); else { mi.Regular = false; mi.Semiregular = false; } // SELF INTERSECTION mi.SelfIntersect = tri::Clean::SelfIntersections(m, mi.intersections); // Mesh Information Output ////////////////////////////////////////// // Print mesh information if(verboseFlag) PrintMeshInfo(mi); // Save mesh information in XML format if(XmlFlag) SaveXMLInfo(mi); // Save mesh information in HTML format if (HtmlFlag) SaveHtmlInfo(mi); // Save the clean mesh if (saveCleanMeshFlag) { printf(" Save the 'clean' mesh..."); tri::io::Exporter::Save(m, SaveName.c_str()); printf(" done.\n\n"); } mi.intersections.clear(); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/msvc/0000755000175000017500000000000012227522351016240 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/msvc/trimeshinfo/0000755000175000017500000000000012227522351020567 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/msvc/trimeshinfo/resource.h0000644000175000017500000000074211517500602022566 0ustar gladkgladk//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by trimeshinfo.rc // #define IDI_ICON1 112 #define IDI_ICON2 113 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 114 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif meshlab-1.3.2+dfsg1/vcglib/apps/msvc/trimeshinfo/trimeshinfo.rc0000644000175000017500000000322511517500602023442 0ustar gladkgladk// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_ICON1 ICON "calibro-detail-2-32.ico" IDI_ICON2 ICON "calibro-detail-2-16.ico" #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED meshlab-1.3.2+dfsg1/vcglib/apps/msvc/metro/0000755000175000017500000000000012227522351017366 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/msvc/metro/metro.rc0000644000175000017500000000366511517500600021046 0ustar gladkgladk// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Italian (Italy) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA) #ifdef _WIN32 LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN #pragma code_page(1252) #endif //_WIN32 ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_ICON1 ICON "metro.ico" #endif // Italian (Italy) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED meshlab-1.3.2+dfsg1/vcglib/apps/msvc/metro/resource.h0000644000175000017500000000066011517500600021362 0ustar gladkgladk//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by metro.rc // #define IDI_ICON1 103 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif meshlab-1.3.2+dfsg1/vcglib/apps/texdeci/0000755000175000017500000000000012227522351016715 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/texdeci/texdeci.cpp0000644000175000017500000002020011573431550021043 0ustar gladkgladk#include #include #include #include // stuff to define the mesh #include #include #include #include #include #include // io #include #include // update #include #include #include // local optimization #include #include #include using namespace vcg; using namespace tri; // The class prototypes. class MyVertex; class MyEdge; class MyFace; struct MyUsedTypes: public UsedTypes::AsVertexType, Use::AsEdgeType, Use::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::VFAdj, vertex::Coord3f, vertex::Normal3f, vertex::Mark, vertex::BitFlags >{ }; class MyEdge : public Edge< MyUsedTypes> {}; typedef BasicVertexPair VertexPair; class MyFace : public Face< MyUsedTypes, face::VFAdj, face::VertexRef, face::BitFlags, face::WedgeTexCoord2f> {}; // the main mesh class class MyMesh : public vcg::tri::TriMesh, std::vector > {}; class MyTriEdgeCollapseQTex: public TriEdgeCollapseQuadricTex< MyMesh, VertexPair, MyTriEdgeCollapseQTex, QuadricTexHelper > { public: typedef TriEdgeCollapseQuadricTex< MyMesh, VertexPair, MyTriEdgeCollapseQTex, QuadricTexHelper > TECQ; inline MyTriEdgeCollapseQTex( const VertexPair &p, int i,BaseParameterClass *pp) :TECQ(p,i,pp){} }; void TexDecimation(MyMesh &m, bool CleaningFlag,int TargetFaceNum) { tri::TriEdgeCollapseQuadricTexParameter pp; pp.SetDefaultParams(); if(CleaningFlag){ int dup = tri::Clean::RemoveDuplicateVertex(m); int unref = tri::Clean::RemoveUnreferencedVertex(m); printf("Removed %i duplicate and %i unreferenced vertices from mesh \n",dup,unref); } printf("reducing it to %i\n",TargetFaceNum); int t1=clock(); tri::UpdateBounding::Box(m); math::Quadric QZero; QZero.SetZero(); QuadricTexHelper::QuadricTemp TD3(m.vert,QZero); QuadricTexHelper::TDp3()=&TD3; std::vector,Quadric5 > > qv; QuadricTexHelper::Quadric5Temp TD(m.vert,qv); QuadricTexHelper::TDp()=&TD; vcg::LocalOptimization DeciSession(m, &pp); // cb(1,"Initializing simplification"); DeciSession.Init(); DeciSession.SetTargetSimplices(TargetFaceNum); DeciSession.SetTimeBudget(0.1f); // int startFn=m.fn; int faceToDel=m.fn-TargetFaceNum; int t2=clock(); while( DeciSession.DoOptimization() && m.fn>TargetFaceNum ) { printf("Simplifing heap size %i ops %i\n",int(DeciSession.h.size()),DeciSession.nPerfmormedOps); }; DeciSession.Finalize(); int t3=clock(); printf("mesh %d %d Error %g \n",m.vn,m.fn,DeciSession.currMetric); printf("\nCompleted in (%i+%i) msec\n",t2-t1,t3-t2); } // mesh to simplify int main(int argc, char**argv){ int meshNum=argc-1; //std::vector meshVec(meshNum); MyMesh meshVec[10]; int tt0=clock(); char buf[255]; int i; for(i=0;i::Open(meshVec[i],argv[i+1]); if(err) { printf("Unable to open mesh %s : '%s'\n",argv[i+1], vcg::tri::io::Importer::ErrorMsg(err)); exit(-1); } printf("mesh loaded %d %d \n",meshVec[i].vn,meshVec[i].fn); int t1=clock(); tri::Smooth::VertexCoordLaplacian(meshVec[i],5*i); TexDecimation(meshVec[i],true,meshVec[i].fn/2); int t2=clock(); printf("%i %5.3f sec\n",i,float(t2-t1)/CLOCKS_PER_SEC); sprintf(buf,"out%i.ply",i); tri::io::ExporterPLY::Save(meshVec[i],buf,false); } int tt1=clock(); printf("---Total %5.3f sec\n",float(tt1-tt0)/CLOCKS_PER_SEC); for(int i=0;i::Save(meshVec[i],buf,tri::io::Mask::IOM_WEDGTEXCOORD,false); } // TriEdgeCollapseQuadricParameter qparams; // qparams.QualityThr =.3; // float TargetError=std::numeric_limits::max(); // bool CleaningFlag =false; // // parse command line. // for(int i=4; i < argc;) // { // if(argv[i][0]=='-') // switch(argv[i][1]) // { // case 'H' : qparams.SafeHeapUpdate=true; printf("Using Safe heap option\n"); break; // case 'Q' : if(argv[i][2]=='y') { qparams.QualityCheck = true; printf("Using Quality Checking\n"); } // else { qparams.QualityCheck = false; printf("NOT Using Quality Checking\n"); } break; // case 'N' : if(argv[i][2]=='y') { qparams.NormalCheck = true; printf("Using Normal Deviation Checking\n"); } // else { qparams.NormalCheck = false; printf("NOT Using Normal Deviation Checking\n"); } break; // case 'O' : if(argv[i][2]=='y') { qparams.OptimalPlacement = true; printf("Using OptimalPlacement\n"); } // else { qparams.OptimalPlacement = false; printf("NOT Using OptimalPlacement\n"); } break; // case 'S' : if(argv[i][2]=='y') { qparams.ScaleIndependent = true; printf("Using ScaleIndependent\n"); } // else { qparams.ScaleIndependent = false; printf("NOT Using ScaleIndependent\n"); } break; // case 'B' : if(argv[i][2]=='y') { qparams.PreserveBoundary = true; printf("Preserving Boundary\n"); } // else { qparams.PreserveBoundary = false; printf("NOT Preserving Boundary\n"); } break; // case 'T' : if(argv[i][2]=='y') { qparams.PreserveTopology = true; printf("Preserving Topology\n"); } // else { qparams.PreserveTopology = false; printf("NOT Preserving Topology\n"); } break; // case 'q' : qparams.QualityThr = atof(argv[i]+2); printf("Setting Quality Thr to %f\n",atof(argv[i]+2)); break; // case 'n' : qparams.NormalThrRad = math::ToRad(atof(argv[i]+2)); printf("Setting Normal Thr to %f deg\n",atof(argv[i]+2)); break; // case 'b' : qparams.BoundaryWeight = atof(argv[i]+2); printf("Setting Boundary Weight to %f\n",atof(argv[i]+2)); break; // case 'e' : TargetError = float(atof(argv[i]+2)); printf("Setting TargetError to %g\n",atof(argv[i]+2)); break; // case 'P' : CleaningFlag=true; printf("Cleaning mesh before simplification\n"); break; // default : printf("Unknown option '%s'\n", argv[i]); // exit(0); // } // i++; // } // if(CleaningFlag){ // int dup = tri::Clean::RemoveDuplicateVertex(mesh); // int unref = tri::Clean::RemoveUnreferencedVertex(mesh); // printf("Removed %i duplicate and %i unreferenced vertices from mesh \n",dup,unref); // } // printf("reducing it to %i\n",FinalSize); // vcg::tri::UpdateBounding::Box(mesh); // // decimator initialization // vcg::LocalOptimization DeciSession(mesh,&qparams); // int t1=clock(); // DeciSession.Init(); // int t2=clock(); // printf("Initial Heap Size %i\n",int(DeciSession.h.size())); // DeciSession.SetTargetSimplices(FinalSize); // DeciSession.SetTimeBudget(0.5f); // if(TargetError< std::numeric_limits::max() ) DeciSession.SetTargetMetric(TargetError); // while(DeciSession.DoOptimization() && mesh.fn>FinalSize && DeciSession.currMetric < TargetError) // printf("Current Mesh size %7i heap sz %9i err %9g \r",mesh.fn, int(DeciSession.h.size()),DeciSession.currMetric); // int t3=clock(); // printf("mesh %d %d Error %g \n",mesh.vn,mesh.fn,DeciSession.currMetric); // printf("\nCompleted in (%i+%i) msec\n",t2-t1,t3-t2); // vcg::tri::io::ExporterPLY::Save(mesh,argv[2]); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/texdeci/texdeci.pro0000644000175000017500000000047511573431550021075 0ustar gladkgladk#DEFINES += VCG_USE_EIGEN TARGET = texdeci #LIBPATH += DEPENDPATH += . ../.. INCLUDEPATH += . ../.. CONFIG += console stl debug_and_release TEMPLATE = app HEADERS += SOURCES += texdeci.cpp ../../wrap/ply/plylib.cpp QT-=gui # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle meshlab-1.3.2+dfsg1/vcglib/apps/shadevis/0000755000175000017500000000000012227522351017076 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/shadevis/visshader.h0000644000175000017500000004042711732414757021260 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.9 2005/11/12 06:47:18 cignoni Added Enhancement, removed type warnings, started to refactor code in order to remove the unnecessary generality of the class. Revision 1.8 2004/09/28 09:45:17 cignoni Added MapFalseColor Revision 1.7 2004/09/16 14:23:57 ponchio fixed gcc template compatibility issues. Revision 1.6 2004/09/10 14:02:20 cignoni Added Cone directions Revision 1.5 2004/09/09 22:59:21 cignoni Removed many small warnings Revision 1.4 2004/09/09 22:37:48 cignoni Integrated lost modifications... Revision 1.3 2004/09/09 14:35:54 ponchio Various changes for gcc compatibility Revision 1.2 2004/07/11 22:13:30 cignoni Added GPL comments ****************************************************************************/ #ifndef __VCG_MESH_VISIBILITY #define __VCG_MESH_VISIBILITY #include #include #include #include #include "simplepic.h" #include namespace vcg { // Base Class che definisce le varie interfaccie; template class VisShader { public : enum {VisMax=MAXVIS}; VisShader(MESH_TYPE &me):m(me) { CullFlag= false; IsClosedFlag = false; ZTWIST=1e-3; SplitNum=1; CameraViewing=false; } typedef Point3 Point3x; typedef typename MESH_TYPE::CoordType CoordType; typedef typename MESH_TYPE::ScalarType ScalarType; typedef typename MESH_TYPE::VertexType VertexType; typedef typename MESH_TYPE::VertexPointer VertexPointer; typedef typename MESH_TYPE::VertexIterator VertexIterator; typedef typename MESH_TYPE::FaceIterator FaceIterator; typedef typename MESH_TYPE::FaceType FaceType; typedef Matrix44 Matrix44x; typedef Box3 Box3x; // The Basic Data the mesh and its wrapper; MESH_TYPE &m; std::vector OMV; // Occluder Mesh Vector; // la visibilita' e' in float, per ogni entita' // 1 significa che e' totalmente visibile per una data direzione. std::vector VV; std::vector< Point3x > VN; // Vettore delle normali che ho usato per calcolare la mask e i float in W; // User defined parameters and flags bool IsClosedFlag; float ZTWIST; bool CullFlag; // Enable the frustum culling. Useful when the splitting value is larger than 2 int SplitNum; protected: bool CameraViewing; //Camera Cam; public: /********************************************************/ // Generic functions with Specialized code for every subclass virtual void MapVisibility(float Gamma=1, float LowPass=0, float HighPass=1,float Scale=1.0)=0; //virtual void ApplyLightingEnvironment(std::vector &W, float Gamma); virtual int GLAccumPixel( std::vector &PixSeen)=0; virtual bool ReadVisibility(const char * /*filename*/){assert( 0); return false;} virtual bool WriteVisibility(const char * /*filename*/){assert( 0); return false;} /********************************************************/ // Generic functions with same code for every subclass void Clear() { fill(VV.begin(),VV.end(),0); } void InitGL() { glPushAttrib(GL_COLOR_BUFFER_BIT ); ::glClearColor (1.0, 1.0, 1.0, 0.0); glMatrixMode (GL_PROJECTION); glPushMatrix(); glMatrixMode (GL_MODELVIEW); glPushMatrix(); } void RestoreGL() { glMatrixMode (GL_PROJECTION); glPopMatrix(); glMatrixMode (GL_MODELVIEW); glPopMatrix(); glPopAttrib(); } /* Funzione principale di conversione in visibilita' Dati i due vettori PixSeen e PixNotSeen che indicano per ogni entita' (vertice o faccia) quanti sono, rispettivamente, i pixel visibili e occlusi, questa funzione calcola un valore float per ogni entita' che indica quanto e' visibile lungo una data direzione camera == 1 significa completamente visibile == 0 significa completamente occluso. */ void AddPixelCount(std::vector &_VV, const std::vector &PixSeen) { assert(_VV.size()==PixSeen.size()); for(unsigned int i=0;i0) _VV[i]+= 1; } //void SetVisibilityMask(std::vector< std::bitset > &_VM, const std::vector &PixSeen, const int dir) // { // assert(_VM.size()==PixSeen.size()); // for(int i=0;i0) _VM[i][dir]=true; // } /******************************* Funzioni ad alto livello che computano le Visibility Mask per varie distribuzioni di direzioni *******************************/ // Funzione Generica // Calcola l'occlusion in base all'insieme VN di direzioni. void Compute( CallBack *cb) { //cb(buf.format("Start to compute %i dir\n",VN.size())); InitGL(); int t00=clock(); VV.resize(m.vert.size()); std::vector PixSeen(VV.size(),0); int TotRay=0,HitRay=0; for(unsigned int i=0;i nvt; assert(0 && "This is only my guess (to compile). (Ponchio)"); assert(0 && "Was: GenNormal(nn*2, nvt);"); GenNormal::Uniform(nn*2,nvt); for(int i=0;i0) VN.push_back(nvt[i]); printf("Asked %i normal, got %i normals\n",nn,VN.size()); Compute(cb); } void ComputeUniformCone(int nn, std::vector &vv, ScalarType AngleRad, Point3x &ConeDir, CallBack *cb) { VN.clear(); GenNormal::UniformCone(nn,VN,AngleRad,ConeDir); typename std::vector::iterator vi; for(vi=VN.begin();vi!=VN.end();++vi) vv.push_back(*vi); char buf[256]; sprintf(buf,"Asked %i normal, got %i normals\n",nn,VN.size()); cb(buf); Compute(cb); } void ComputeUniform(int nn, std::vector &vv, CallBack *cb) { VN.clear(); GenNormal::Uniform(nn,VN); typename std::vector::iterator vi; for(vi=VN.begin();vi!=VN.end();++vi) vv.push_back(*vi); char buf[256]; sprintf(buf,"Asked %i normal, got %i normals\n",nn,VN.size()); cb(buf); Compute(cb); } void ComputeSingle(Point3x &dir, std::vector &vv,CallBack *cb) { VN.clear(); VN.push_back(dir); vv.push_back(dir); printf("Computing one direction (%f %f %f)\n",dir[0],dir[1],dir[2]); Compute(cb); } /**********************************************************/ int SplittedRendering(Point3x &ViewDir, std::vector &PixSeen, CallBack *cb=DummyCallBack) { int tt=0; int i,j; for(i=0;i &PixSeen, CallBack *cb=DummyCallBack) { int t0=clock(); std::string buf; int added=SplittedRendering(BaseDir, PixSeen,cb); int t1=clock(); printf("ComputeSingleDir %i msec\n",t1-t0); } void ComputeAverageVisibilityDirection() { int i,j; VD.resize(VM.size()); for(j=0;j &msk=VM[j]; for(i=0;i &LE, Point3x dir, ScalarType DegAngle1, ScalarType DegAngle2) { LE.clear(); LE.resize(VN.size(),0); int i; for(i=0;iDegAngle2) { LE[i]=0; continue; } LE[i] = 1.0-(a-DegAngle1)/(DegAngle2-DegAngle1); } // last step normalize the weights; ScalarType sum=0; for(i=0;i class VertexVisShader : public VisShader { public : // Function Members VertexVisShader(MESH_TYPE &me):VisShader(me) { // la mesh DEVE avere colore per vertice if(! HasPerVertexColor(m)) assert(0); } void Init() { VV.resize(m.vert.size()); } void Compute(int nn); void DrawFill (MESH_TYPE &mm) { static GLuint dl=0; if(mm.face.empty()) { AMesh::VertexIterator vi; glBegin(GL_POINTS); for(vi=mm.vert.begin();vi!=mm.vert.end();++vi) { if(ColorFlag) glColor((*vi).C()); glVertex((*vi).P()); } glEnd(); } else { glBegin(GL_TRIANGLES); FaceIterator fi; for(fi=mm.face.begin();fi!=mm.face.end();++fi) { glVertex((*fi).V(0)->P()); glVertex((*fi).V(1)->P()); glVertex((*fi).V(2)->P()); } glEnd(); } } /***************************************************************************/ //VertexVisibility // Funzione Principale restituisce per ogni entita' quanti px si vedono o no. int GLAccumPixel( std::vector &PixSeen) { SimplePic snapZ; SimplePic snapC; glClearColor(Color4b::Black); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT ); glDisable(GL_LIGHTING); glDepthRange(0.0f,1.0f); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glDepthMask(GL_TRUE); glDrawBuffer(GL_BACK); glReadBuffer(GL_BACK); /////** Si disegnano le front face **///// glDepthRange(2.0*ZTWIST,1.0f); if(IsClosedFlag) glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glColor(Color4b::Red); DrawFill(m); if(!IsClosedFlag) { glCullFace(GL_FRONT); glColor(Color4b::Black); DrawFill(m); snapC.OpenGLSnap(); } int cnt=0; snapZ.OpenGLSnap(GL_DEPTH_COMPONENT); glDepthRange(0,1.0f-2.0*ZTWIST); double MM[16]; glGetDoublev(GL_MODELVIEW_MATRIX,MM); double MP[16]; glGetDoublev(GL_PROJECTION_MATRIX,MP); int VP[4]; glGetIntegerv(GL_VIEWPORT,VP); double tx,ty,tz; for(unsigned int i=0;i=0 && tx=0 && ty VV2; std::vector VC(VV.size(),1); VV2=VV; for(fi=m.face.begin();fi!=m.face.end();++fi) for(int i=0;i<3;++i) { VV2[(*fi).V(i)-&*m.vert.begin()] += VV[(*fi).V1(i)-&*m.vert.begin()]; ++VC[(*fi).V(i)-&*m.vert.begin()]; } if(!Enhance) for(unsigned int i=0;iHighPass) gval=HighPass; (*vi).C().SetGrayShade(Scale*pow((gval-LowPass)/(HighPass-LowPass),Gamma)); } } //void ApplyLightingEnvironment(std::vector &W, float Gamma=1) // { // assert(W.size()==VN.size()); // MESH_TYPE::VertexIterator vi; // // for(vi=m.vert.begin();vi!=m.vert.end();++vi) // { // float gray=0; // bitset &msk=VM[vi-m.vert.begin()]; // for(int i=0;i set the number of sampling direction (default 64, but 100~500 should be better) -f flip normal of the surface -z specify the z tolerance used to decide if a vertex is visible against the zbuffer or not (default 1e-3, useful range 1e-3 .. 1e-6) meshlab-1.3.2+dfsg1/vcglib/apps/shadevis/simplepic.h0000644000175000017500000000576511517500570021251 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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 __VCG_SIMPLE_PIC #define __VCG_SIMPLE_PIC #include namespace vcg { template class SimplePic {public: std::vector img; int sx,sy; void Create(int tx,int ty) { sx=tx;sy=ty; img.resize(sx*sy); } PixType &Pix(int x, int y) {return img[sx*y+x];} void OpenGLSnap(GLenum format=0) { int vp[4]; glGetIntegerv( GL_VIEWPORT,vp ); // Lettura viewport glPixelStorei( GL_PACK_ROW_LENGTH, 0); glPixelStorei( GL_PACK_ALIGNMENT, 1); int tx = vp[2]; int ty = vp[3]; Create(tx,ty); GLenum mtype = 0; if(format==0) { format = GL_RGBA; mtype = GL_UNSIGNED_BYTE; } if(format==GL_DEPTH_COMPONENT) { format = GL_DEPTH_COMPONENT; mtype = GL_FLOAT; } glReadPixels(vp[0],vp[1],vp[2],vp[3],format,mtype,(GLvoid *)&img[0]); } bool SavePPM( const char * filename ) { FILE * fp = fopen(filename,"wb"); if(fp==0) return false; fprintf(fp,"P6\n%d %d\n255\n",sx,sy); for(int i=0;i #include #include #include // this define is mandatory to avoid the conflicts due to the silly definition of // min and max macros in windows.h (included by glut...) #define NOMINMAX #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "visshader.h" using namespace vcg; using namespace std; // Vertex, Face, Mesh and Grid definitions. class MyEdge; class AFace; class AVertex : public VertexVCVN< float ,MyEdge,AFace > {}; class AFace : public FaceFN< AVertex,MyEdge,AFace > {}; class AMesh : public tri::TriMesh< vector, vector > {}; ///////// Global //////// int SampleNum=64; int WindowRes=800; unsigned int TexInd=0; bool SwapFlag=false; bool CullFlag=false; bool ClosedFlag=false; Point3f ConeDir(0,1,0); float ConeAngleRad = math::ToRad(180.0f); float lopass=0,hipass=1,gamma_correction=1; float diff=.8; float ambi=.2; bool LightFlag=true; bool ColorFlag=true; bool FalseColorFlag=false; bool ShowDirFlag=false; int imgcnt=0; Color4b BaseColor=Color4b::White; Trackball QV; Trackball QL; Trackball *Q=&QV; int ScreenH,ScreenW; float ViewAngle=33; vector ViewVector; bool cb(const char *buf) { printf(buf); return true; } void BuildOnePixelTexture(Color4b c, unsigned int &TexInd) { if(TexInd==0) glGenTextures(1,&TexInd); glBindTexture(GL_TEXTURE_1D,TexInd); glTexImage1D(GL_TEXTURE_1D,0,GL_RGBA,1,0,GL_RGBA,GL_UNSIGNED_BYTE,&c); glEnable(GL_TEXTURE_1D); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); } void glutPrintf(int x, int y, const char * f, ... ) { glMatrixMode (GL_PROJECTION); glPushMatrix(); glLoadIdentity (); glOrtho(0,ScreenW,0,ScreenH,-1,1); glMatrixMode (GL_MODELVIEW); glPushMatrix(); glLoadIdentity (); int len, i; char buf[4096]; va_list marker; va_start( marker, f ); int n = vsprintf(buf,f,marker); va_end( marker ); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glColor3f(0,0,0); glRasterPos2f(x, y); len = (int) strlen(buf); for (i = 0; i < len; i++) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, buf[i]); } glMatrixMode (GL_PROJECTION); glPopMatrix(); glMatrixMode (GL_MODELVIEW); glPopMatrix(); glPopAttrib(); } // prototypes void SaveTexturedGround(); void DrawViewVector() { glDisable(GL_LIGHTING); glColor3f(0,0,1); glBegin(GL_LINES); for(unsigned int i=0;iN()); if(ColorFlag) glColor((*fi).V(0)->C()); glVertex((*fi).V(0)->P()); glNormal((*fi).V(1)->N()); if(ColorFlag) glColor((*fi).V(1)->C()); glVertex((*fi).V(1)->P()); glNormal((*fi).V(2)->N()); if(ColorFlag) glColor((*fi).V(2)->C()); glVertex((*fi).V(2)->P()); } glEnd(); } } AMesh m; VertexVisShader Vis(m); string OutNameMsh; /* Called when the window is first opened and whenever * the window is reconfigured (moved or resized). */ void ViewReshape(GLsizei w, GLsizei h) { ScreenW=w; ScreenH=h; glViewport(0,0,w,h); } void ViewDisplay (void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(ViewAngle,(float)ScreenW/ScreenH,1,7); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glPushMatrix(); QL.Apply(); glutPrintf(5,5,"Diffuse %04.2f Ambient %04.2f " " LowPass %04.2f HiPass %04.2f Gamma %04.2f rgb = %03i:%03i:%03i", diff,ambi,lopass,hipass,gamma_correction,BaseColor[0],BaseColor[1],BaseColor[2]); GLfloat light_position0[] = {0.0, 10.0, 300.0, 0.0}; glLightfv(GL_LIGHT0, GL_POSITION, light_position0); glPopMatrix(); glTranslatef(0,0,-4); if(Q==&QL) DrawLightVector(); QL.GetView(); QV.GetView(); QV.Apply(false); if(ShowDirFlag) DrawViewVector(); float d = 2.0/m.bbox.Diag(); glScalef(d, d, d); glColor3f(diff,diff,diff); glTranslate(-m.bbox.Center()); if(LightFlag) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); if(ColorFlag) glEnable(GL_COLOR_MATERIAL); else glDisable(GL_COLOR_MATERIAL); if(FalseColorFlag) glColorMaterial(GL_FRONT,GL_DIFFUSE); else glColorMaterial(GL_FRONT,GL_AMBIENT); glMateriali(GL_FRONT,GL_SHININESS,0); float spec[4]={0,0,0,1}; float ambientV[4]={ambi,ambi,ambi,1}; float diffuseV[4]={diff,diff,diff,1}; glMaterialfv(GL_FRONT,GL_SPECULAR,spec); glMaterialfv(GL_FRONT,GL_AMBIENT, ambientV); glMaterialfv(GL_FRONT,GL_DIFFUSE, diffuseV); glCullFace(GL_BACK); if(CullFlag) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); BuildOnePixelTexture(BaseColor,TexInd); Draw(m); glutSwapBuffers(); } void ViewSpecialKey(int , int , int ) { glutPostRedisplay(); } void Toggle(bool &flag) {flag = !flag;} void UpdateVis() { if( LightFlag && !FalseColorFlag) Vis.MapVisibility(gamma_correction,lopass,hipass,ambi); if(!LightFlag && !FalseColorFlag) Vis.MapVisibility(gamma_correction,lopass,hipass,1.0); if(FalseColorFlag) Vis.MapFalseColor(); } /*********************************************************************/ /*********************************************************************/ /*********************************************************************/ void ViewKey(unsigned char key, int , int ) { Point3f dir; switch (key) { case 27: exit(0); break; case 9: if(Q==&QV) Q=&QL;else Q=&QV; break; case 'l' : lopass=lopass+.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction); UpdateVis(); break; case 'L' : lopass=lopass-.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction); UpdateVis(); break; case 'h' : hipass=hipass-.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction); UpdateVis(); break; case 'H' : hipass=hipass+.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction); UpdateVis(); break; case 'd' : diff+=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break; case 'D' : diff-=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break; case 'a' : ambi+=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break; case 'A' : ambi-=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break; case 'e' : ambi+=.05; diff-=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break; case 'E' : ambi-=.05; diff+=.05; printf("Ambient %f Diffuse %f, \n",ambi,diff); UpdateVis(); break; case 'p' : gamma_correction=gamma_correction-.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction); UpdateVis(); break; case 'P' : gamma_correction=gamma_correction+.05; printf("Lo %f, Hi %f Gamma %f\n",lopass,hipass,gamma_correction); UpdateVis(); break; case 13 : //Vis.ComputeUniform(SampleNum,ViewVector,cb); Vis.ComputeUniformCone(SampleNum,ViewVector, ConeAngleRad,ConeDir,cb); UpdateVis(); break; case ' ' : { Point3f dir = Q->camera.ViewPoint(); printf("ViewPoint %f %f %f\n",dir[0],dir[1],dir[2]); dir.Normalize(); dir=Inverse(Q->track.Matrix())*dir; printf("ViewPoint %f %f %f\n",dir[0],dir[1],dir[2]); dir.Normalize(); Vis.ComputeSingle(dir,ViewVector,cb); UpdateVis(); } break; case 'r' : BaseColor[0]=min(255,BaseColor[0]+2); break; case 'R' : BaseColor[0]=max( 0,BaseColor[0]-2); break; case 'g' : BaseColor[1]=min(255,BaseColor[1]+2); break; case 'G' : BaseColor[1]=max( 0,BaseColor[1]-2); break; case 'b' : BaseColor[2]=min(255,BaseColor[2]+2); break; case 'B' : BaseColor[2]=max( 0,BaseColor[2]-2); break; case 'v' : Toggle(ShowDirFlag); break; case 'V' : { SimplePic snapC; snapC.OpenGLSnap(); char buf[128]; sprintf(buf,"Snap%03i.ppm",imgcnt++); snapC.SavePPM(buf); } case 's' : Vis.SmoothVisibility(); UpdateVis(); break; case 't' : Vis.SmoothVisibility(true); UpdateVis(); break; case 'S' : { vcg::tri::io::PlyInfo p; p.mask|=vcg::tri::io::Mask::IOM_VERTCOLOR /* | vcg::ply::PLYMask::PM_VERTQUALITY*/ ; tri::io::ExporterPLY::Save(m,OutNameMsh.c_str(),false,p); } break; case 'C' : LightFlag = !LightFlag; printf("Toggled Light %s\n",LightFlag?"on":"off"); UpdateVis(); break; case 'c' : ColorFlag = !ColorFlag; printf("Toggled Color %s\n",ColorFlag?"on":"off"); break; case 'f' : FalseColorFlag = !FalseColorFlag; printf("Toggled FalseColor %s\n",ColorFlag?"on":"off"); UpdateVis(); break; case '1' : diff=0.80f; ambi=0.10f; gamma_correction=1.0; lopass=0.00f; hipass=1.00f; ColorFlag=false; UpdateVis(); break; case '2' : diff=0.65f; ambi=0.30f; gamma_correction=1.0; lopass=0.15f; hipass=0.80f; ColorFlag=true; UpdateVis(); break; case '3' : diff=0.45f; ambi=0.50f; gamma_correction=1.0; lopass=0.20f; hipass=0.75f; ColorFlag=true; UpdateVis(); break; case '4' : diff=0.35f; ambi=0.60f; gamma_correction=1.0; lopass=0.25f; hipass=0.70f; ColorFlag=true; UpdateVis(); break; } glutPostRedisplay(); ; } void ViewMenu(int val) { ViewKey(val, 0, 0); } /*********************************************************************/ // TrackBall Functions /*********************************************************************/ int GW,GH; // Grandezza della finestra void ViewMouse(int button, int state, int x, int y) { static int KeyMod=0; static int glut_buttons=0; //printf("ViewMouse %i %i %i %i\n",x,y,button,state); int m_mask = 0; if(state == GLUT_DOWN) { KeyMod=glutGetModifiers(); if(GLUT_ACTIVE_SHIFT & KeyMod) m_mask |= Trackball::KEY_SHIFT; if(GLUT_ACTIVE_ALT & KeyMod) m_mask |= Trackball::KEY_ALT; if(GLUT_ACTIVE_CTRL & KeyMod) m_mask |= Trackball::KEY_CTRL; glut_buttons |= (1<MouseDown(x, ScreenH-y, glut_buttons | m_mask); } else { if(GLUT_ACTIVE_SHIFT & KeyMod) m_mask |= Trackball::KEY_SHIFT; if(GLUT_ACTIVE_ALT & KeyMod) m_mask |= Trackball::KEY_ALT; if(GLUT_ACTIVE_CTRL & KeyMod) m_mask |= Trackball::KEY_CTRL; glut_buttons |= (1<MouseUp(x, ScreenH-y, glut_buttons | m_mask); } } void ViewMouseMotion(int x, int y) { Q->MouseMove(x,ScreenH-y); glutPostRedisplay(); } void SetLight() { GLfloat light_ambient0[] = {0.0, 0.0, 0.0, 1.0}; GLfloat light_diffuse0[] = {1.0, 1.0, 1.0, 1.0}; GLfloat light_position0[] = {0.0, 10.0, 300.0, 0.0}; glLightfv(GL_LIGHT0, GL_POSITION, light_position0); glLightfv(GL_LIGHT0, GL_AMBIENT, light_diffuse0); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0); glEnable(GL_LIGHT0); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,light_ambient0); } void ViewInit (void) { SetLight(); Q->Reset(); Q->radius= 1; glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearColor (0.8, 0.8, 0.8, 0.0); glEnable(GL_NORMALIZE); glEnable(GL_LIGHTING); // glEnable(GL_BLEND); glShadeModel(GL_SMOOTH); // glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); } int main(int argc, char** argv) { if(argc<2) { printf( "shadevis 1.0 \n"__DATE__"\n" "Copyright 2003-2004 Visual Computing Lab I.S.T.I. C.N.R.\n" "Paolo Cignoni (cignoni@isti.cnr.it)\n\n" "Usage: shadevis file.ply [options]\n" "Options:\n" " -w# WindowResolution (default 600)\n" " -n# Sample Directions (default 64)\n" " -z# z offset (default 1e-3)\n" " -c assume that the mesh is closed (slightly faster, default false)\n" " -f Flip normal of the model\n" " -da # Cone Direction Angle in degree (default 180)\n" " -dv # # # Cone Direction vector (default 0 0 1)\n" ); return 1; } srand(time(0)); int i=1; while(i::Open(m,argv[i]); if(ret) {printf("Error unable to open mesh %s : '%s' \n",argv[i],tri::io::ImporterPLY::ErrorMsg(ret));exit(-1);} tri::UpdateNormals::PerVertexNormalized(m); tri::UpdateBounding::Box(m); tri::UpdateColor::VertexConstant(m,Color4b::White); Vis.IsClosedFlag=ClosedFlag; Vis.Init(); UpdateVis(); printf("Mesh bbox (%f %f %f)-(%f %f %f)\n\n", m.bbox.min[0],m.bbox.min[1],m.bbox.min[2], m.bbox.max[0],m.bbox.max[1],m.bbox.max[2]); OutNameMsh=(string(argv[i]).substr(0,strlen(argv[i])-4)); OutNameMsh+="_vis.ply"; printf("Mesh Output filename %s\n",OutNameMsh.c_str()); printf("Mesh %iv %if bbox Diag %g\n",m.vn,m.fn,m.bbox.Diag()); glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize(WindowRes, WindowRes); glutInitWindowPosition (10,10); glutCreateWindow ("shadevis - Visual Computing Lab - vcg.isti.cnr.it "); glutDisplayFunc(ViewDisplay); glutReshapeFunc(ViewReshape); glutKeyboardFunc(ViewKey); glutSpecialFunc(ViewSpecialKey); glutMouseFunc(ViewMouse); glutMotionFunc(ViewMouseMotion); ViewInit(); glewInit(); glutMainLoop(); return(0); } meshlab-1.3.2+dfsg1/vcglib/apps/shadevis/history.txt0000644000175000017500000000127411517500570021344 0ustar gladkgladk VCGLib http://vcg.sf.net o o Visual and Computer Graphics Library o o _ O _ Copyright(C) 2005-2006 \/)\/ Visual Computing Lab http://vcg.isti.cnr.it /\/| ISTI - Italian National Research Council | \ ShadeVis 1.00 2005/11/11 All rights reserved. 2005/11/11 Release 1.00 Initial Releasemeshlab-1.3.2+dfsg1/vcglib/apps/tetra_decimator/0000755000175000017500000000000012227522351020436 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/tetra_decimator/main.cpp0000644000175000017500000000375511551320500022067 0ustar gladkgladk #include // stuff to define the mesh #include #include #include // io #include #include #include class MyEdge; class MyTetrahedron; class MyFace; class MyVertex:public vcg::VertexATVMVNf{} ; class MyTetrahedron : public vcg::TetraATAVTQ{}; class MyTMesh: public vcg::tetra::Tetramesh< std::vector, std::vector >{}; #include #include vcg::LocalOptimization *loc; //vcg::tetra::TetraEdgeCollapse c; MyTMesh mesh; int main(int,char**argv,int num_op){ loc=new vcg::LocalOptimization(mesh); vcg::tetra::io::ImporterTS::Open(mesh,argv[1]); //vcg::tetra::io::ImporterTS::Open(mesh,"d:/sphere.ts"); printf("mesh loaded %d %d \n",mesh.vn,mesh.tn); /*vcg::tetra::TetraEdgeCollapse *_ ; bool res;*/ vcg::tetra::UpdateTetraTopology ::VTTopology(mesh.vert,mesh.tetra); vcg::tetra::UpdateTetraTopology ::TTTopology(mesh.vert,mesh.tetra); vcg::tetra::UpdateTetraTopology ::setExternalVertices(mesh.vert,mesh.tetra); vcg::tetra::TetraEdgeCollapse::Init(mesh,loc->h); bool res; do{ loc->SetTargetOperations(num_op); res = loc->DoOptimization(); printf("ood %d\n bor %d\n vol %d \n lkv %d \n lke %d \n lkf %d \n", FAIL::OFD(), FAIL::BOR(), FAIL::VOL(), FAIL::LKV(), FAIL::LKE(), FAIL::LKF() ); printf("mesh %d %d \n",mesh.vn,mesh.tn); }while(!res); vcg::tetra::io::ExporterPLY::Save(mesh,"out.ply"); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/tridecimator/0000755000175000017500000000000012227522351017756 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/tridecimator/tridecimator.pro0000644000175000017500000000042611651743673023204 0ustar gladkgladk TARGET = tridecimator DEPENDPATH += ../.. INCLUDEPATH += . ../.. CONFIG += console stl debug_and_release TEMPLATE = app HEADERS += SOURCES += tridecimator.cpp ../../wrap/ply/plylib.cpp # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle meshlab-1.3.2+dfsg1/vcglib/apps/tridecimator/tridecimator.cpp0000644000175000017500000001745211614570175023167 0ustar gladkgladk#include #include #include #include // stuff to define the mesh #include #include #include #include #include #include // io #include #include // update #include // local optimization #include #include using namespace vcg; using namespace tri; /********************************************************** Mesh Classes for Quadric Edge collapse based simplification For edge collpases we need verteses with: - V->F adjacency - per vertex incremental mark - per vertex Normal Moreover for using a quadric based collapse the vertex class must have also a Quadric member Q(); Otherwise the user have to provide an helper function object to recover the quadric. ******************************************************/ // The class prototypes. class MyVertex; class MyEdge; class MyFace; struct MyUsedTypes: public UsedTypes::AsVertexType,Use::AsEdgeType,Use::AsFaceType>{}; class MyVertex : public Vertex< MyUsedTypes, vertex::VFAdj, vertex::Coord3f, vertex::Normal3f, vertex::Mark, vertex::BitFlags >{ public: vcg::math::Quadric &Qd() {return q;} private: math::Quadric q; }; class MyEdge : public Edge< MyUsedTypes> {}; typedef BasicVertexPair VertexPair; class MyFace : public Face< MyUsedTypes, face::VFAdj, face::VertexRef, face::BitFlags > {}; // the main mesh class class MyMesh : public vcg::tri::TriMesh, std::vector > {}; class MyTriEdgeCollapse: public vcg::tri::TriEdgeCollapseQuadric< MyMesh, VertexPair, MyTriEdgeCollapse, QInfoStandard > { public: typedef vcg::tri::TriEdgeCollapseQuadric< MyMesh, VertexPair, MyTriEdgeCollapse, QInfoStandard > TECQ; typedef MyMesh::VertexType::EdgeType EdgeType; inline MyTriEdgeCollapse( const VertexPair &p, int i, BaseParameterClass *pp) :TECQ(p,i,pp){} }; void Usage() { printf( "---------------------------------\n" " TriSimp V.1.0 \n" " http://vcg.isti.cnr.it\n" " http://vcg.sourceforge.net\n" " release date: "__DATE__"\n" "---------------------------------\n\n" "TriDecimator 1.0 \n"__DATE__"\n" "Copyright 2003-2012 Visual Computing Lab I.S.T.I. C.N.R.\n" "\nUsage: "\ "tridecimator fileIn fileOut face_num [opt]\n"\ "Where opt can be:\n"\ " -e# QuadricError threshold (range [0,inf) default inf)\n" " -b# Boundary Weight (default .5)\n" " -q# Quality threshold (range [0.0, 0.866], default .3 )\n" " -n# Normal threshold (degree range [0,180] default 90)\n" " -E# Minimal admitted quadric value (default 1e-15, must be >0)\n" " -Q[y|n] Use or not Quality Threshold (default yes)\n" " -N[y|n] Use or not Normal Threshold (default no)\n" " -A[y|n] Use or not Area Weighted Quadrics (default yes)\n" " -O[y|n] Use or not vertex optimal placement (default yes)\n" " -S[y|n] Use or not Scale Independent quadric measure(default yes) \n" " -B[y|n] Preserve or not mesh boundary (default no)\n" " -T[y|n] Preserve or not Topology (default no)\n" " -H[y|n] Use or not Safe Heap Update (default no)\n" " -P Before simplification, remove duplicate & unreferenced vertices\n" ); exit(-1); } // mesh to simplify MyMesh mesh; int main(int argc ,char**argv){ if(argc<4) Usage(); int FinalSize=atoi(argv[3]); //int t0=clock(); int err=vcg::tri::io::Importer::Open(mesh,argv[1]); if(err) { printf("Unable to open mesh %s : '%s'\n",argv[1],vcg::tri::io::Importer::ErrorMsg(err)); exit(-1); } printf("mesh loaded %d %d \n",mesh.vn,mesh.fn); TriEdgeCollapseQuadricParameter qparams; qparams.QualityThr =.3; float TargetError=std::numeric_limits::max(); bool CleaningFlag =false; // parse command line. for(int i=4; i < argc;) { if(argv[i][0]=='-') switch(argv[i][1]) { case 'H' : qparams.SafeHeapUpdate=true; printf("Using Safe heap option\n"); break; case 'Q' : if(argv[i][2]=='y') { qparams.QualityCheck = true; printf("Using Quality Checking\n"); } else { qparams.QualityCheck = false; printf("NOT Using Quality Checking\n"); } break; case 'N' : if(argv[i][2]=='y') { qparams.NormalCheck = true; printf("Using Normal Deviation Checking\n"); } else { qparams.NormalCheck = false; printf("NOT Using Normal Deviation Checking\n"); } break; case 'O' : if(argv[i][2]=='y') { qparams.OptimalPlacement = true; printf("Using OptimalPlacement\n"); } else { qparams.OptimalPlacement = false; printf("NOT Using OptimalPlacement\n"); } break; case 'S' : if(argv[i][2]=='y') { qparams.ScaleIndependent = true; printf("Using ScaleIndependent\n"); } else { qparams.ScaleIndependent = false; printf("NOT Using ScaleIndependent\n"); } break; case 'B' : if(argv[i][2]=='y') { qparams.PreserveBoundary = true; printf("Preserving Boundary\n"); } else { qparams.PreserveBoundary = false; printf("NOT Preserving Boundary\n"); } break; case 'T' : if(argv[i][2]=='y') { qparams.PreserveTopology = true; printf("Preserving Topology\n"); } else { qparams.PreserveTopology = false; printf("NOT Preserving Topology\n"); } break; case 'q' : qparams.QualityThr = atof(argv[i]+2); printf("Setting Quality Thr to %f\n",atof(argv[i]+2)); break; case 'n' : qparams.NormalThrRad = math::ToRad(atof(argv[i]+2)); printf("Setting Normal Thr to %f deg\n",atof(argv[i]+2)); break; case 'b' : qparams.BoundaryWeight = atof(argv[i]+2); printf("Setting Boundary Weight to %f\n",atof(argv[i]+2)); break; case 'e' : TargetError = float(atof(argv[i]+2)); printf("Setting TargetError to %g\n",atof(argv[i]+2)); break; case 'P' : CleaningFlag=true; printf("Cleaning mesh before simplification\n"); break; default : printf("Unknown option '%s'\n", argv[i]); exit(0); } i++; } if(CleaningFlag){ int dup = tri::Clean::RemoveDuplicateVertex(mesh); int unref = tri::Clean::RemoveUnreferencedVertex(mesh); printf("Removed %i duplicate and %i unreferenced vertices from mesh \n",dup,unref); } printf("reducing it to %i\n",FinalSize); vcg::tri::UpdateBounding::Box(mesh); // decimator initialization vcg::LocalOptimization DeciSession(mesh,&qparams); int t1=clock(); DeciSession.Init(); int t2=clock(); printf("Initial Heap Size %i\n",int(DeciSession.h.size())); DeciSession.SetTargetSimplices(FinalSize); DeciSession.SetTimeBudget(0.5f); if(TargetError< std::numeric_limits::max() ) DeciSession.SetTargetMetric(TargetError); while(DeciSession.DoOptimization() && mesh.fn>FinalSize && DeciSession.currMetric < TargetError) printf("Current Mesh size %7i heap sz %9i err %9g \r",mesh.fn, int(DeciSession.h.size()),DeciSession.currMetric); int t3=clock(); printf("mesh %d %d Error %g \n",mesh.vn,mesh.fn,DeciSession.currMetric); printf("\nCompleted in (%i+%i) msec\n",t2-t1,t3-t2); vcg::tri::io::ExporterPLY::Save(mesh,argv[2]); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/tridecimator/history.txt0000644000175000017500000000213711517500570022223 0ustar gladkgladk VCGLib http://vcg.sf.net o o Visual and Computer Graphics Library o o _ O _ Copyright(C) 2005-2006 \/)\/ Visual Computing Lab http://vcg.isti.cnr.it /\/| ISTI - Italian National Research Council | \ Metro 4.04 25/01/2005 All rights reserved. 2005/04/04 Release 4.05 Added saving of Error Histogram 2005/01/26 Release 4.04 Gcc compiling issues Moved to the library core the code for computing min distance froma a point to a mesh using a uniform grid. Slightly faster. 2005/01/03 Release 4.03 Better ply compatibility, and improved error reporting 2004/11/29 Release 4.02 removed bug in printing Hausdorf distance, removed bug in command line parsing, upgraded import mesh library to support off format meshlab-1.3.2+dfsg1/vcglib/apps/tridecimator/readme.txt0000644000175000017500000000713011517500570021755 0ustar gladkgladk VCGLib http://vcg.sf.net o o Visual and Computer Graphics Library o o _ O _ Copyright(C) 2005-2006 \/)\/ Visual Computing Lab http://vcg.isti.cnr.it /\/| ISTI - Italian National Research Council | \ TriDecimator 1.00 2/10/2005 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. --- Synopsis --- tridecimator fileIn fileOut face_num [opt]\ Where opt can be:\ -e# QuadricError threshold (range [0,inf) default inf) -b# Boundary Weight (default .5) -q# Quality threshold (range [0.0, 0.866], default .3 ) -n# Normal threshold (degree range [0,180] default 90) -E# Minimal admitted quadric value (default 1e-15, must be >0) -Q[y|n] Use or not Quality Threshold (default yes) -N[y|n] Use or not Normal Threshold (default no) -A[y|n] Use or not Area Weighted Quadrics (default yes) -O[y|n] Use or not vertex optimal placement (default yes) -S[y|n] Use or not Scale Independent quadric measure(default yes) -B[y|n] Preserve or not mesh boundary (default no) -T[y|n] Preserve or not Topology (default no) -H[y|n] Use or not Safe Heap Update (default no) -P Before simplification, remove duplicate & unreferenced vertices Supported formats: PLY, OFF, STL -- Some technical notes -- This simplification tool employ a quadric error based edge collapse iterative approach. Each possible collapse is scored taking into account - its quadric error - its quadric boundary error - the normal variation caused by the collapse itself - the future quality (aspect ratio) of the triangles involved in the collapse The simplification can ends when the desired number of triangles has been reached. The 'Safe Heap Update' change the set of edges re-inserted in the heap after a collapse resulting in a vertex v; this option put back in the heap not only incident in the vbut all the edges of the triangles incident in v. It slows down a lot. The 'Scale Independent quadric' is useful when you want simplify two different meshes at the same 'error'; otherwise the quadric error used in the heap is somewhat normalized and independent of the size of the mesh. The Normal threshold avoid to make large changes in variation of the normal of the surfaces, but on the other hand it prevent the removal of small 'folded' triangles that can be already present. Therefore in most cases is not very useful. Cleaning the mesh is mandatory for some input format like STL that always duplicates all the vertices. meshlab-1.3.2+dfsg1/vcglib/apps/pivoting/0000755000175000017500000000000012227522351017127 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/pivoting/pivot.h0000644000175000017500000006045011551320477020452 0ustar gladkgladk#ifndef VCG_PIVOT_H #define VCG_PIVOT_H #include #include #include "vcg/space/index/grid_static_ptr.h" #include "vcg/complex/algorithms/closest.h" namespace vcg { namespace tri { struct Hinge { int v0, v1, v2; //v0, v1 represent the Hinge, v2 the other vertex in the face //this Hinge belongs to int face; //corresponding face Point3f center; //center of the sphere touching the face int count; //test delay touch Hinges. //the loops in the front are mantained as a double linked list std::list::iterator next; std::list::iterator previous; Hinge() {} Hinge(int _v0, int _v1, int _v2, int _face, Point3f &_center): v0(_v0), v1(_v1), v2(_v2), face(_face), center(_center), count(0) { assert(v0 != v1 && v1 != v2 && v0 != v2); } }; template class Pivot { public: // typedef CMesh MESH; typedef GridStaticPtr StaticGrid; float radius; //default 1 (not meaningful float mindist; //minimum distance between points in the mesh (% of radius) float crease; // -0.5 Box3f box; MESH &mesh; StaticGrid grid; /* front Hinges of the mesh: to expand the front we get the first Hinge if an Hinge cannot create a new triangle it is marked dead and moved to the end of the list the new Hinges are inserted to the back (before dead_begin) */ std::list front; std::list deads; std::vector nb; //number of fronts a vertex is into, //this is used for the Visited and Border flags //but adding topology may not be needed anymode Pivot(MESH &_mesh, float _radius, float _mindist = 0.05, float _crease = -0.5): mesh(_mesh), radius(_radius), mindist(_mindist), crease(_crease) { //Compute bounding box. (this may be passed as a parameter? for(int i = 0; i < mesh.vert.size(); i++) box.Add(mesh.vert[i].P()); /* we need to enlarge the grid to allow queries from little outside of the box Someone is a bit lazy... */ box.Offset(4*radius); grid.Set(mesh.vert.begin(), mesh.vert.end(), box); nb.clear(); nb.resize(mesh.vert.size(), 0); for(int i = 0; i < mesh.vert.size(); i++) mesh.vert[i].ClearFlags(); } /* select a vertex at random, a small group of nearby vertices and looks for a sphere that touches 3 and contains none. Use the center of the box to get a sphere inside (or outside) the model You may be unlucky... */ bool seed(bool outside = true, int start = -1) { //pick a random point (well...) if(start == -1) start = rand()%mesh.vert.size(); //get a sphere of neighbours std::vector targets; std::vector dists; int n = getInSphere(mesh.vert[start].P(), 2*radius, targets, dists); if(n < 3) { //bad luck. we should call seed again (assuming random pick) up to //some maximum tries. im lazy. return false; } int v0, v1, v2; bool found = false; //find a triplet that does not contains any other point Point3f center; for(int i = 0; i < n; i++) { v0 = targets[i]; CVertex &vv0 = mesh.vert[v0]; if(vv0.IsD() || vv0.IsB() || vv0.IsV()) continue; Point3f &p0 = mesh.vert[v0].P(); Point3f out = (p0 - box.Center()); if(!outside) out = -out; for(int k = i+1; k < n; k++) { v1 = targets[k]; CVertex &vv1 = mesh.vert[v1]; if(vv1.IsD() || vv1.IsB() || vv1.IsV()) continue; Point3f &p1 = mesh.vert[v1].P(); if((p1 - p0).Norm() < mindist*radius) continue; for(int j = k+1; j < n; j++) { v2 = targets[j]; CVertex &vv2 = mesh.vert[v2]; if(vv2.IsD() || vv2.IsB() || vv2.IsV()) continue; Point3f &p2 = mesh.vert[v2].P(); if((p2 - p0).Norm() < mindist*radius) continue; if((p2 - p1).Norm() < mindist*radius) continue; Point3f normal = (p1 - p0)^(p2 - p0); //check normal pointing inside if(normal * out < 0) continue; if(!findSphere(p0, p1, p2, center)) continue; bool failed = false; //check no other point inside for(int t = 0; t < n; t++) { Point3f &p = mesh.vert[targets[t]].P(); if((center - p).Norm() <= radius) { failed = true; break; } } if(failed) continue; found = true; i = k = j = n; } } } if(!found) //see bad luck above return false; assert(!front.size()); //TODO: should i check the Hinges too? addFace(v0, v1, v2); //create the border of the first face std::list::iterator e = front.end(); std::list::iterator last; for(int i = 0; i < 3; i++) { int v0 = (int)(mesh.face.back().V0(i)); int v1 = (int)(mesh.face.back().V1(i)); int v2 = (int)(mesh.face.back().V2(i)); nb[v0] = 1; assert(!mesh.vert[v0].IsB()); mesh.vert[v0].SetB(); Hinge Hinge(v0, v1, v2, 0, center); Hinge.previous = e; e = front.insert(front.begin(), Hinge); if(i == 0) last = e; (*Hinge.previous).next = e; cluster(v0); } //connect last and first (*e).next = last; (*last).previous = e; return true; } /* expand the front adding 1 face. Return false on failure (id when all Hinges are dead returns: 1: added a face 0: added nothing -1: finished */ int addFace() { //We try to seed again if(!mesh.face.size()) { for(int i = 0; i < 100; i++) if(seed()) return 1; return -1; } if(!front.size()) { //maybe there are unconnected parts of the mesh: //find a non D, V, B point and try to seed if failed D it. for(int i = 0; i < mesh.vert.size();i ++) { CVertex &v = mesh.vert[i]; if(v.IsD() || v.IsV() || v.IsB()) continue; if(seed(true, i)) return 1; v.SetD(); } return -1; } std::list::iterator ei = front.begin(); Hinge &e = *ei; Hinge &previous = *e.previous; Hinge &next = *e.next; int v0 = e.v0, v1 = e.v1; //last triangle missing. or it is the first? if(0 &&next.next == e.previous) { int v[3] = { previous.v0, next.v0, e.v0 }; int c[3] = { 0, 0, 0 }; for(int k = 0; k < 3; k++) { int vert = v[k]; nb[vert]--; if(nb[vert] == 0) { mesh.vert[vert].SetV(); mesh.vert[vert].ClearB(); } } assert(previous.previous == e.next); addFace(previous.v0, next.v0, e.v0); front.erase(e.previous); front.erase(e.next); front.erase(ei); return 1; } int v2; Point3f center; std::vector targets; bool success = pivot(e, v2, center, targets); //if no pivoting move this thing to the end and try again //or we are trying to connect to the inside of the mesh. BAD. if(!success || mesh.vert[v2].IsV()) { killHinge(ei); return 0; } //does v2 belongs to a front? (and which?) std::list::iterator touch = touches(v2, ei); assert(v2 != v0 && v2 != v1); int fn = mesh.face.size(); if(touch != front.end()) { if(!checkHinge(v0, v2) || !checkHinge(v2, v1)) { killHinge(ei); return 0; } if(v2 == previous.v0) { /*touching previous Hinge (we reuse previous) next ------->v2 -----> v1------> \ / \ / previous \ / e \ / v0 */ detach(v0); previous.v1 = v1; previous.v2 = v0; previous.face = fn; previous.center = center; previous.next = e.next; next.previous = e.previous; moveBack(e.previous); //this checks if we can glue something to e.previous trovamiunnome(e.previous); front.erase(ei); } else if(v2 == next.v1) { /*touching previous Hinge (we reuse next) previous ------->v0 -----> v2------> \ / \ / \ / next \ / v1 */ detach(v1); next.v0 = v0; next.v2 = v1; next.face = fn; next.center = center; next.previous = e.previous; previous.next = e.next; // moveBack(e.next); //this checks if we can glue something to e.previous trovamiunnome(e.next); front.erase(ei); } else { /* this code would delay the joining Hinge to avoid bad situations not used but.. if(e.count < 2) { e.count++; moveBack(ei); return true; }*/ //touching some loop: split (or merge it is local does not matter. //like this /* left right <--------v2-<------ /|\ / \ up / \ down / \ / V ----v0 - - - > v1--------- e */ std::list::iterator left = touch; std::list::iterator right = (*touch).previous; std::list::iterator up = ei; if(v1 == (*right).v0 || v0 == (*left).v1) { // cout << "Bad join.\n"; killHinge(ei); return 0; } nb[v2]++; std::list::iterator down = newHinge(Hinge(v2, v1, v0, fn, center)); (*right).next = down; (*down).previous = right; (*down).next = e.next; next.previous = down; (*left).previous = up; (*up).next = left; (*up).v2 = v1; (*up).v1 = v2; (*up).face = fn; (*up).center = center; moveBack(ei); } } else { assert(!mesh.vert[v2].IsB()); //fatal error! a new point is already a border? /* adding a new vertex v2 /|\ / \ up / \ down / \ / V ----v0 - - - > v1--------- */ cluster(v2); nb[v2]++; mesh.vert[v2].SetB(); std::list::iterator down = newHinge(Hinge(v2, v1, v0, fn, center)); (*down).previous = ei; (*down).next = e.next; next.previous = down; e.v2 = v1; e.v1 = v2; e.face = fn; e.center = center; e.next = down; moveBack(ei); } addFace(v0, v2, v1); return 1; } /* return new vertex and the center of the new sphere pivoting from Hinge if the vertex belongs to another Hinge, touch points to it. */ bool pivot(Hinge &Hinge, int &candidate, Point3f &end_pivot, std::vector &targets) { Point3f v0 = mesh.vert[Hinge.v0].P(); Point3f v1 = mesh.vert[Hinge.v1].P(); Point3f v2 = mesh.vert[Hinge.v2].P(); /* TODO why using the face normals everything goes wrong? should be exactly the same................................................ Check if the e.face is correct. Point3f &normal = mesh.face[Hinge.face].N(); */ Point3f normal = ((v1 - v0)^(v2 - v0)).Normalize(); Point3f middle = (v0 + v1)/2; Point3f start_pivot = Hinge.center - middle; Point3f axis = (v1 - v0); float axis_len = axis.SquaredNorm(); if(axis_len > 4*radius*radius) return false; axis.Normalize(); // r is the radius of the thorus of all possible spheres passing throug v0 and v1 float r = sqrt(radius*radius - axis_len/4); std::vector dists; getInSphere(middle, r + radius, targets, dists); if(targets.size() == 0) return false; //this really would be strange but one never knows. candidate = -1; float minangle = 0; Point3f center; //to be computed for each sample for(int i = 0; i < targets.size(); i++) { int id = targets[i]; if(id == Hinge.v0 || id == Hinge.v1 || id == Hinge.v2) continue; if(mesh.vert[id].IsD()) { continue; } Point3f p = mesh.vert[id].P(); /* Prevent 360 Hinges, also often reject ~ 50% points */ Point3f n = ((p - v0)^(v1 - v0)).Normalize(); if(n * normal < -0.5) { continue; } /* Find the sphere through v0, p, v1 (store center on end_pivot */ if(!findSphere(v0, p, v1, center)) { continue; } /* Angle between old center and new center */ float alpha = angle(start_pivot, center - middle, axis); /* adding a small bias to already chosen vertices. doesn't solve numerical problems, but helps. */ if(mesh.vert[id].IsB()) alpha -= 0.001; /* Sometimes alpha might be little less then M_PI while it should be 0, by numerical errors: happens for example pivoting on the diagonal of a square. */ if(alpha > 2*M_PI - 0.8) { // Angle between old center and new *point* //TODO is this really overshooting? shouldbe enough to alpha -= 2*M_PI Point3f proj = p - axis * (axis * p - axis * middle); float beta = angle(start_pivot, proj - middle, axis); if(alpha > beta) alpha -= 2*M_PI; } if(candidate == -1 || alpha < minangle) { candidate = id; minangle = alpha; end_pivot = center; } } //found no point suitable. if(candidate == -1) { return false; } assert(candidate != Hinge.v0 && candidate != Hinge.v1); return true; } private: //front management: //Add a new Hinge to the back of the queue std::list::iterator newHinge(Hinge e) { return front.insert(front.end(), e); } //move an Hinge among the dead ones void killHinge(std::list::iterator e) { deads.splice(deads.end(), front, e); } //move an Hinge to the back of the queue void moveBack(std::list::iterator e) { front.splice(front.end(), front, e); } void moveFront(std::list::iterator e) { front.splice(front.begin(), front, e); } bool checkHinge(int v0, int v1) { int tot = 0; //HACK to speed up things until i can use a seach structure int i = mesh.face.size() - 2*(front.size()); // i = 0; if(i < 0) i = 0; for(; i < mesh.face.size(); i++) { CFace &f = mesh.face[i]; for(int k = 0; k < 3; k++) { if(v1== (int)f.V(k) && v0 == (int)f.V((k+1)%3)) ++tot; else if(v0 == (int)f.V(k) && v1 == (int)f.V((k+1)%3)) { //orientation non constistent return false; } } if(tot >= 2) { //non manifold return false; } } return true; } void Pivot::cluster(int v) { /* clean up too close points */ std::vector targets; std::vector dists; getInSphere(mesh.vert[v].P(), mindist*radius, targets, dists); for(int i = 0; i < targets.size(); i++) { int id = targets[i]; if(id == v) continue; CVertex &v = mesh.vert[id]; if(v.IsD() || v.IsV() || v.IsB()) continue; v.SetD(); } } void Pivot::trovamiunnome(std::list::iterator e) { if(glue((*e).previous, e)) return; glue(e, (*e).next); } //glue toghether a and b (where a.next = b bool Pivot::glue(std::list::iterator a, std::list::iterator b) { if((*a).v0 != (*b).v1) return false; std::list::iterator previous = (*a).previous; std::list::iterator next = (*b).next; (*previous).next = next; (*next).previous = previous; detach((*a).v1); detach((*a).v0); front.erase(a); front.erase(b); return true; } void Pivot::detach(int v) { assert(nb[v] > 0); if(--nb[v] == 0) { mesh.vert[v].SetV(); mesh.vert[v].ClearB(); } } /* compute angle from p to q, using axis for orientation */ float angle(Point3f p, Point3f q, Point3f &axis) { p.Normalize(); q.Normalize(); Point3f vec = p^q; float angle = acos(p*q); if(vec*axis < 0) angle = -angle; if(angle < 0) angle += 2*M_PI; return angle; } /* add a new face. compute normals. */ void addFace(int a, int b, int c) { CFace face; face.V(0) = (CVertex *)a; face.V(1) = (CVertex *)b; face.V(2) = (CVertex *)c; Point3f &p0 = mesh.vert[a].P(); Point3f &p1 = mesh.vert[b].P(); Point3f &p2 = mesh.vert[c].P(); face.N() = ((p1 - p0)^(p2 - p0)).Normalize(); mesh.face.push_back(face); mesh.fn++; } /* intersects segment [v0, v1] with the sphere of radius radius. */ bool intersect(int v0, int v1, Point3f ¢er) { Point3f m = mesh.vert[v1].P() - mesh.vert[v0].P(); float t = m*(center - mesh.vert[v0].P()); if(t < 0) return false; if(t > m*m) return false; return true; } float distance(int v0, int v1, Point3f ¢er) { Point3f m = mesh.vert[v1].P() - mesh.vert[v0].P(); float t = m*(center - mesh.vert[v0].P())/(m*m); Point3f p = mesh.vert[v0].P() + m*t; return (p - center).Norm(); } /* return all point in a given ball, notice as i want the index of the vertices not the pointers... this may change in future */ unsigned int getInSphere(vcg::Point3f &p, float distance, std::vector &results, std::vector &dists) { std::vector ptr; std::vector points; int n = vcg::tri::GetInSphereVertex(mesh, grid, p, distance, ptr, dists, points); for(int i = 0; i < ptr.size(); i++) results.push_back(ptr[i] - &(mesh.vert[0])); return n; } /* returns the sphere touching p0, p1, p2 of radius r such that the normal of the face points toward the center of the sphere */ bool findSphere(Point3f &p0, Point3f &p1, Point3f &p2, Point3f ¢er) { Point3f q1 = p1 - p0; Point3f q2 = p2 - p0; Point3f up = q1^q2; float uplen = up.Norm(); //the three points are aligned if(uplen < 0.001*q1.Norm()*q2.Norm()) return false; up /= uplen; float a11 = q1*q1; float a12 = q1*q2; float a22 = q2*q2; float m = 4*(a11*a22 - a12*a12); float l1 = 2*(a11*a22 - a22*a12)/m; float l2 = 2*(a11*a22 - a12*a11)/m; center = q1*l1 + q2*l2; float circle_r = center.Norm(); if(circle_r > radius) return false; //need too big a sphere float height = sqrt(radius*radius - circle_r*circle_r); center += p0 + up*height; return true; } std::list::iterator touches(int v, std::list::iterator e) { //TODO what happens when it touches more than one front? //might still work. std::list::iterator touch = front.end(); if(mesh.vert[v].IsB()) { //test nearby Hinges: it is faster std::list::iterator p = e; p = (*e).previous; if(v == (*p).v0) return p; e = (*e).next; if(v == (*e).v0) return e; p = (*p).previous; if(v == (*p).v0) return p; e = (*e).next; if(v == (*e).v0) return e; //test all. sigh. for(std::list::iterator k = front.begin(); k != front.end(); k++) { if(v == (*k).v0) { touch = k; break; } } for(std::list::iterator k = deads.begin(); k != deads.end(); k++) { if(v == (*k).v0) { touch = k; break; } } assert(touch != front.end()); } return touch; } public: }; }//namespace }//namespace /* CODE FOR PIVOTING IN A TOUCH SITUATION not used now. //if touch we want to check the ball could really pivot around that point if(touch != front.end() && touch != (*Hinge.next).next && touch != Hinge.previous) { Point3f &hinge = mesh.vert[min].P(); Point3f target = (*touch).center - hinge; float d = (target * start_pivot)/(target.Norm()*start_pivot.Norm()); if(d < -0.8) { return false; } if(d < 0.5) { //they are far enough so test . Point3f naxis = (target ^ start_pivot).Normalize(); Point3f d1 = naxis^start_pivot; Point3f d2 = target^naxis; for(int i = 0; i < targets.size(); i++) { int id = targets[i]; if(id == Hinge.v0 || id == Hinge.v1 || id == Hinge.v2 || id == min) continue; if(mesh.vert[id].IsD()) { continue; } Point3f intruder = mesh.vert[targets[i]].P() - hinge; float h = intruder*naxis; if(fabs(h) > radius) continue; intruder -= naxis*h; assert(fabs(intruder *naxis) < 0.01); float off = radius - intruder.Norm(); //(distance from the center ring of the thorus if(h*h + off*off > radius*radius) continue; //outside of thorus if(d1*intruder < 0 || d2*intruder < 0) continue; //ouside of sector cout << "could not pivot while touching;\n"; return false; } } }*/ #endif meshlab-1.3.2+dfsg1/vcglib/apps/pivoting/curvature.h0000644000175000017500000000000011517500565021312 0ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/pivoting/glarea.h0000644000175000017500000000272711551320477020547 0ustar gladkgladk#ifndef CG_RENDERAREA_H #define CG_RENDERAREA_H #include #include #include #include #include #include "cmesh.h" //#include "mls_surface.h" //#include "advancing.h" using namespace tri; using namespace trimesh; class GLArea : public QGLWidget { Q_OBJECT public: GLArea(QWidget *parent = 0); bool smooth; public slots: bool loadModel(const QString &file); void addFace(); void add10Faces(); void add100Faces(); void add1000Faces(); void addAll(); void setTot(int n) { tot = n; } void addTot(); void open(); void save(); void setRadius(double _radius) { radius = _radius; } void viewSmooth(bool on); protected: int tot; float radius; vcg::Box3f box; CMesh mesh; // Pivot *pivot; Pivot *pivot; vcg::Trackball trackball; void init(QString file, float radius); void draw(); void initializeGL(); void resizeGL(int w, int h); void paintGL(); void wheelEvent(QWheelEvent *e); void mouseMoveEvent(QMouseEvent *e); void mousePressEvent(QMouseEvent *e); void mouseReleaseEvent(QMouseEvent *e); void keyReleaseEvent ( QKeyEvent * e ); }; #endif meshlab-1.3.2+dfsg1/vcglib/apps/pivoting/glarea.cpp0000644000175000017500000002446311551320477021103 0ustar gladkgladk #include #include #include #include #include #include #include #include "glarea.h" #include "cmesh.h" #include #include #include #include #include #include //#include "curvature.h" using namespace std; using namespace vcg; GLArea::GLArea(QWidget *parent): QGLWidget(parent), pivot(NULL), smooth(false), radius(1.2) { tot = 1; setMouseTracking(true); // init("uccello.ply", radius); } bool GLArea::loadModel(const QString &file) { updateGL(); return true; } void GLArea::open() { QString file = QFileDialog::getOpenFileName(this, "Select a ply file", "", "*.ply"); if(!file.size()) return; init(file, radius); } void GLArea::init(QString file, float ballsize = 1.2) { int err = tri::io::Importer::Open(mesh, file.toAscii().data()); if(err) return; mesh.face.clear(); mesh.fn = 0; // UpdateTopology::VertexFace(mesh); // UpdateTopology::FaceFace(mesh); // tri::UpdateFlags::FaceBorderFromFF(mesh); // tri::UpdateFlags::VertexBorderFromFace(mesh); //compute box; box = Box3f(); for(int i = 0; i < mesh.vert.size(); i++) box.Add(mesh.vert[i].P()); float r = sqrt((box.Diag()*box.Diag())/mesh.vn); // mesh.face.clear(); // mesh.fn = 0; if(pivot) delete pivot; cout << "creating pibot\n"; NormalExtrapolation >::ExtrapolateNormals(mesh.vert.begin(), mesh.vert.end(), 10); // pivot = new Pivot(mesh, r*ballsize, 0.1, 0); pivot = new Pivot(mesh, 0, 0.1, 0); // pivot.build(); // pivot->buildMesh(); } void GLArea::save() { mesh.vn = mesh.vert.size(); mesh.fn = mesh.face.size(); tri::io::ExporterPLY::Save(mesh, "prova.ply"); } void GLArea::addFace() { pivot->addFace(); updateGL(); /* std::list::iterator li; for(li=pivot->front.begin();li!=pivot->front.end();++li) printf("(%d-%d-%d)",(*li).v0,(*li).v1,(*li).v2); printf("\n");*/ } void GLArea::add10Faces() { for(int i =0; i < 10; i++) if(-1 == pivot->addFace()) return; updateGL(); } void GLArea::add100Faces() { for(int i =0; i < 100; i++) if(-1 == pivot->addFace()) return; updateGL(); } void GLArea::add1000Faces() { for(int i =0; i < 1000; i++) if(-1 == pivot->addFace()) return; updateGL(); } void GLArea::addAll() { while(1) { for(int i = 0; i < 1000; i++) if(0 > pivot->addFace()) return; updateGL(); } } void GLArea::addTot() { for(int i = 0; i < tot; i++) if(0 > pivot->addFace()) return; updateGL(); } void GLArea::viewSmooth(bool on) { smooth = on; updateGL(); } void GLArea::initializeGL() { glClearColor(1, 1, 1, 1); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glDisable(GL_BLEND); glEnable(GL_NORMALIZE); glDisable(GL_CULL_FACE); glCullFace(GL_BACK); glColor4f(1, 1, 1, 1); glEnable(GL_LIGHTING); double st = 4; //1/sqrt(3); float lpos[4]; lpos[0] = lpos[1] = lpos[2] = st; lpos[3] = 1; glLightfv(GL_LIGHT0, GL_POSITION, lpos); float v[4] = {0.8, 0.8, 0.8, 0.0}; glLightfv(GL_LIGHT0, GL_DIFFUSE, v); trackball.center=Point3f(0, 0, 0); trackball.radius= 1; glLoadIdentity(); } void GLArea::resizeGL(int w, int h) { glViewport(0, 0, (GLint)w, (GLint)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float r = w/(float)h; gluPerspective(60, r, 1, 4); glMatrixMode(GL_MODELVIEW); } void GLArea::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glLoadIdentity(); gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0); //Drawing the scene glPushMatrix(); trackball.GetView(); trackball.Apply(true); Point3f c = -box.Center(); float radius = 2.0f/box.Diag(); if(mesh.face.size()>0) { CFace &face = mesh.face[0]; CVertex *v[3]; v[0] = face.V(0); c=-v[0]->P(); radius=radius*5; } if(!pivot) return; glPushMatrix(); glScalef(radius, radius, radius); glTranslatef(c[0], c[1], c[2]); if(pivot->front.size()>2) { glEnable(GL_LINE_SMOOTH); glColor4f(1, 0, 1, 0.1); glLineWidth(5); Pivot::Edgex &ee=pivot->front.front(); int v0=ee.v0; int v1=ee.v1; glBegin(GL_LINES); glVertex3fv(mesh.vert[v0].P().V()); glVertex3fv(mesh.vert[v1].P().V()); glEnd(); glLineWidth(1); } glEnable(GL_LIGHTING); glColor3f(0, 1, 0); glBegin(GL_TRIANGLES); for(int i = 0; i < mesh.face.size(); i++) { CFace &face = mesh.face[i]; CVertex *v[3]; v[0] = face.V(0); v[1] = face.V(1); v[2] = face.V(2); Point3f n = (v[1]->P()- v[0]->P()) ^ (v[2]->P() - v[0]->P()); //Point3f &n = face.N(); glNormal3fv(&(n[0])); for(int k = 0; k < 3; k++) { glVertex3fv((float *)&(v[k]->P())); } } glEnd(); glEnable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(-3, -3); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDisable(GL_LIGHTING); glColor3f(0, 0.5, 0); glPolygonOffset(-1, -1); glBegin(GL_TRIANGLES); for(int i = 0; i < mesh.face.size(); i++) { CFace &face = mesh.face[i]; CVertex *v[3]; v[0] = face.V(0); v[1] = face.V(1); v[2] = face.V(2); for(int k = 0; k < 3; k++) { glVertex3fv((float *)&(v[k]->P())); } } glEnd(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_DEPTH_TEST); glLineWidth(3.0f); glBegin(GL_LINES); for(list::Edgex>::iterator k = pivot->front.begin(); k != pivot->front.end(); k++) { glColor3f(1, 0, 0); Point3f &p0 = mesh.vert[(*k).v0].P(); glVertex3fv(&(p0[0])); glColor3f(0, 0, 1); Point3f &p1 = mesh.vert[(*k).v1].P(); glVertex3fv(&(p1[0])); /* glColor3f(1, 1, 0); Point3f middle = (mesh.vert[(*k).v0].P() + mesh.vert[(*k).v1].P())/2; glVertex3fv(&(middle[0])); glVertex3fv(&((*k).center[0]));*/ } for(list::Edgex>::iterator k = pivot->deads.begin(); k != pivot->deads.end(); k++) { glColor3f(0, 0, 0); Point3f &p0 = mesh.vert[(*k).v0].P(); glVertex3fv(&(p0[0])); Point3f &p1 = mesh.vert[(*k).v1].P(); glVertex3fv(&(p1[0])); } glEnd(); glEnable(GL_DEPTH_TEST); glPointSize(4.0f); glBegin(GL_POINTS); for(int i = 0; i < mesh.vert.size(); i++) { CVertex &v = mesh.vert[i]; Point3f &p = v.P(); if(v.IsD()) continue; if(v.IsV()) glColor3f(1, 0, 0); else if(v.IsB()) glColor3f(1, 1, 0); else continue; glVertex3f(p[0], p[1], p[2]); } glEnd(); glColor3f(0, 0, 0); glPointSize(1.0f); glLineWidth(1.0f); glEnable(GL_LIGHTING); glBegin(GL_LINES); for(int i = 0; i < mesh.vert.size(); i++) { CVertex &v = mesh.vert[i]; Point3f &p = v.P(); if(v.IsD()) continue; glVertex3f(p[0], p[1], p[2]); Point3f q = p + v.N(); glVertex3f(q[0], q[1], q[2]); } glEnd(); glDisable(GL_POLYGON_OFFSET_LINE); glDisable(GL_LIGHTING); glPopMatrix(); glScalef(radius, radius, radius); glTranslatef(c[0], c[1], c[2]); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // cloud.draw(); glColor3f(0.5, 0.5, 0.5); glPointSize(2); glBegin(GL_POINTS); for(int i = 0; i < mesh.vert.size(); i++) { CVertex &vert = mesh.vert[i]; Point3f n = vert.N(); Point3f p = vert.P(); glNormal3f(n[0], n[1], n[2]); glVertex3f(p[0], p[1], p[2]); } glEnd(); glDisable(GL_BLEND); glPopMatrix(); } void GLArea::wheelEvent(QWheelEvent *e) { if(e->delta() > 0) trackball.MouseWheel(1); else trackball.MouseWheel(-1); updateGL(); } void GLArea::mouseMoveEvent(QMouseEvent *e) { trackball.MouseMove(e->x(), height() - e->y()); updateGL(); } Trackball::Button QT2VCG(Qt::MouseButton qtbt, Qt::KeyboardModifiers modifiers) { int vcgbt=Trackball::BUTTON_NONE; if(qtbt & Qt::LeftButton ) vcgbt |= Trackball::BUTTON_LEFT; if(qtbt & Qt::RightButton ) vcgbt |= Trackball::BUTTON_RIGHT; if(qtbt & Qt::MidButton ) vcgbt |= Trackball::BUTTON_MIDDLE; if(modifiers & Qt::ShiftModifier ) vcgbt |= Trackball::KEY_SHIFT; if(modifiers & Qt::ControlModifier ) vcgbt |= Trackball::KEY_CTRL; if(modifiers & Qt::AltModifier ) vcgbt |= Trackball::KEY_ALT; return Trackball::Button(vcgbt); } void GLArea::keyReleaseEvent ( QKeyEvent * e ) { if(e->key()==Qt::Key_Control) trackball.MouseUp(0,0, QT2VCG(Qt::NoButton, Qt::ControlModifier ) ); if(e->key()==Qt::Key_Shift) trackball.MouseUp(0,0, QT2VCG(Qt::NoButton, Qt::ShiftModifier ) ); if(e->key()==Qt::Key_Alt) trackball.MouseUp(0,0, QT2VCG(Qt::NoButton, Qt::AltModifier ) ); } void GLArea::mousePressEvent(QMouseEvent *e) { trackball.MouseDown(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) ); // if(e->button() == Qt::LeftButton) //trackball.MouseDown(e->x(), width() - e->y(), Trackball::BUTTON_LEFT); // if(e->button() == Qt::RightButton) // trackball.MouseDown(e->x(), width() - e->y(), Trackball::BUTTON_LEFT | Trackball::KEY_CTRL); updateGL(); } void GLArea::mouseReleaseEvent(QMouseEvent *e) { trackball.MouseUp(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) ); // if(e->button() == Qt::LeftButton) //trackball.MouseUp(e->x(), width() - e->y(), Trackball::BUTTON_LEFT); //if(e->button() == Qt::RightButton) // trackball.MouseUp(e->x(), width() - e->y(), Trackball::BUTTON_LEFT | Trackball::KEY_CTRL); } meshlab-1.3.2+dfsg1/vcglib/apps/pivoting/mainwindow.ui0000644000175000017500000002525711517500565021661 0ustar gladkgladk MainWindow 0 0 717 727 128 128 128 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 128 128 128 255 255 255 128 128 128 255 255 255 255 255 255 0 0 0 49 106 197 255 255 255 0 0 255 255 0 255 255 255 255 128 128 128 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 128 128 128 255 255 255 128 128 128 255 255 255 255 255 255 0 0 0 49 106 197 255 255 255 0 0 255 255 0 255 255 255 255 128 128 128 255 255 255 255 255 255 255 255 255 127 127 127 170 170 170 128 128 128 255 255 255 128 128 128 255 255 255 255 255 255 0 0 0 49 106 197 255 255 255 0 0 255 255 0 255 255 255 255 MainWindow 9 6 1 1 0 0 120 70 120 300 9 6 10000000 1 Add Add 1 face Add 100 faces Add 10 faces Open... smooth 10 0.5 0.1 1.2 Save <html><head><meta name="qrichtext" content="1" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">R:</span></p></body></html> Add 1000 faces Add all Qt::Vertical QSizePolicy::MinimumExpanding 20 271 7 7 0 0 GLArea QFrame
glarea.h
0
meshlab-1.3.2+dfsg1/vcglib/apps/pivoting/cmesh.h0000644000175000017500000000232411551320477020404 0ustar gladkgladk#ifndef CLOTH_MESH_H #define CLOTH_MESH_H #include #include #include #include #include #include #include using namespace vcg; class CVertex; class CEdge; class CFace; class CEdge { public: CVertex *v[2]; CFace *f; bool operator<(const CEdge& t) const { if(v[0] < t.v[0]) return true; if(v[0] > t.v[0]) return false; return v[1] < t.v[1]; } bool operator==(const CEdge& t) const { return v[0] == t.v[0] && v[1] == t.v[1]; } }; class CVertex: public VertexSimp2 { public: float color; }; class CFace: public FaceSimp2 {}; class CMesh: public tri::TriMesh< std::vector, std::vector > {}; #endif meshlab-1.3.2+dfsg1/vcglib/apps/pivoting/ring.h0000644000175000017500000000517711517500565020255 0ustar gladkgladk#ifndef RING_H #define RING_H // Making a "ring" data structure from the STL #include using namespace std; template class ring { list lst; public: ring &operator=(const ring *r) { lst = r->lst; } // Declaration necessary so the following // 'friend' statement sees this 'iterator' // instead of std::iterator: class iterator; friend class iterator; class iterator : public std::iterator { public: typename list::iterator it; list* r; // "typename" necessary to resolve nesting: iterator(): r(NULL) {} iterator(list& lst, const typename list::iterator& i) : r(&lst), it(i) {} iterator &operator=(const iterator& x) { it = x.it; r = x.r; return *this; } bool operator==(const iterator& x) const { return it == x.it; } bool operator!=(const iterator& x) const { return !(*this == x); } typename list::reference operator*() const { return *it; } iterator& operator++() { ++it; if(it == r->end()) it = r->begin(); return *this; } iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; } iterator& operator--() { if(it == r->begin()) it = r->end(); --it; return *this; } iterator operator--(int) { iterator tmp = *this; --*this; return tmp; } iterator operator+(int i) { iterator tmp = *this; while(i--) ++tmp; return tmp; } iterator operator-(int i) { iterator tmp = *this; while(i--) --tmp; return tmp; } iterator insert(const T& x){ return iterator(*r, r->insert(it, x)); } iterator erase() { iterator tmp = iterator(*r, r->erase(it)); if (tmp.it == r->end()) tmp.it = r->begin(); return tmp; } }; iterator insert(iterator &i, const T& x) { typename list::iterator it; it = lst.insert(i.it, x); return iterator(lst, it); } iterator push_back(const T& x) { typename list::iterator it; it = lst.insert(lst.end(), x); return iterator(lst, it); } /* void push_back(const T& x) { lst.push_back(x); }*/ iterator begin() { return iterator(lst, lst.begin()); } int size() { return lst.size(); } void clear() { lst.clear(); } void reverse() { lst.reverse(); } void erase(iterator &i) { lst.erase(i.it); } }; #endif meshlab-1.3.2+dfsg1/vcglib/apps/pivoting/main.cpp0000644000175000017500000000524611517500565020572 0ustar gladkgladk#include using namespace std; #include #include "mainwindow.h" class QMyWindow: public QMainWindow { public: QMyWindow(QWidget *parent): QMainWindow(parent) { ui.setupUi(this); if(!connect(ui.add_face, SIGNAL(clicked()), ui.area, SLOT(addFace()))) { cerr << "Could not connect addface\n"; } if(!connect(ui.add_10_faces, SIGNAL(clicked()), ui.area, SLOT(add10Faces()))) { cerr << "Could not connect addface\n"; } if(!connect(ui.add_100_faces, SIGNAL(clicked()), ui.area, SLOT(add100Faces()))) { cerr << "Could not connect addface\n"; } if(!connect(ui.add_1000_faces, SIGNAL(clicked()), ui.area, SLOT(add1000Faces()))) { cerr << "Could not connect addface\n"; } if(!connect(ui.add_all, SIGNAL(clicked()), ui.area, SLOT(addAll()))) { cerr << "Could not connect addface\n"; } if(!connect(ui.add, SIGNAL(clicked()), ui.area, SLOT(addTot()))) { cerr << "Could not connect addface\n"; } if(!connect(ui.save, SIGNAL(clicked()), ui.area, SLOT(save()))) { cerr << "Could not connect addface\n"; } if(!connect(ui.smooth, SIGNAL(clicked(bool)), ui.area, SLOT(viewSmooth(bool)))) { cerr << "Could not connect addface\n"; } if(!connect(ui.open, SIGNAL(clicked()), ui.area, SLOT(open()))) { cerr << "Could not connect addface\n"; } if(!connect(ui.radius, SIGNAL(valueChanged(double)), ui.area, SLOT(setRadius(double)))) { cerr << "Could not connect addface\n"; } if(!connect(ui.tot, SIGNAL(valueChanged(int)), ui.area, SLOT(setTot(int)))) { cerr << "Could not connect addface\n"; } /* connect(ui.world, SIGNAL(activated(const QString&)), ui.area, SLOT(loadWorld(const QString&))); connect(ui.shadow, SIGNAL(activated(int)), ui.area, SLOT(setShadowMode(int))); connect(ui.drawvolume, SIGNAL(clicked(bool)), ui.area, SLOT(setDrawVolume(bool))); connect(ui.track, SIGNAL(activated(int)), ui.area, SLOT(setTrackMode(int)));*/ } private: Ui::MainWindow ui; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QMyWindow *window = new QMyWindow(NULL); window->show(); return app.exec(); } meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/0000755000175000017500000000000012227522351017631 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/tetrastats.h0000644000175000017500000000176311517500570022207 0ustar gladkgladk template class TetraStats { typedef typename TETRA_MESH_TYPE::TetraType TetraType; TETRA_MESH_TYPE * Tetra; TetraType* T; public: double volume; double ratio; TetraStats(){T=0;} ~TetraStats(){} static double ComputeVolume(TETRA_MESH_TYPE *tm) { double total=0.f; TETRA_MESH_TYPE::TetraIterator ti; for (ti=tm->tetra.begin();titetra.end();ti++) { if (!ti->IsD()) total+=ti->ComputeVolume(); } return total; } static double ComputeRatioMedia(TETRA_MESH_TYPE *tm) { double total=0.f; TETRA_MESH_TYPE::TetraIterator ti; int i=0; for (ti=tm->tetra.begin();titetra.end();ti++) { if (!ti->IsD()) { total+=ti->AspectRatio(); i++; } } return (total/i); } void SetTetraMesh(TETRA_MESH_TYPE* T) { Tetra=T; } void Update() { ratio=ComputeRatioMedia(Tetra); volume=ComputeVolume(Tetra); } void SetTetraInfo(TetraType *Te) { if (T!=0) T->ClearS(); T=Te; } void ClearTetraInfo(TetraType *Te) { T=0; } TetraType * TCurrent() { return T; } }; meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/qmake_image_collection.cpp0000644000175000017500000000143711517500570025015 0ustar gladkgladk/**************************************************************************** ** Image collection for project 'TetraView'. ** ** Generated from reading image files: ** images/editcopy ** images/editcut ** images/editpaste ** images/filenew ** images/fileopen ** images/filesave ** images/print ** images/redo ** images/searchfind ** images/undo ** images/Open64.png ** ** Created: Mon Oct 4 19:00:57 2004 ** by: The User Interface Compiler ($Id: qmake_image_collection.cpp,v 1.3 2004-10-04 18:01:36 ganovelli Exp $) ** ** WARNING! All changes made in this file will be lost! ****************************************************************************/ #include #include #include #include meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/myclasses.h0000644000175000017500000000070011517500570022002 0ustar gladkgladk#include #include #include class MyTetrahedron; class DUMMYEDGETYPE; class DUMMYFACETYPE; class MyVertex: public vcg::VertexATVNd{}; class MyTetrahedron: public vcg::TetraATAV{}; typedef vcg::tetra::Tetramesh< std::vector ,std::vector > MyTetraMesh; meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/mainframe.cpp0000644000175000017500000002523411517500570022302 0ustar gladkgladk/**************************************************************************** ** Form implementation generated from reading ui file 'MainFrame.ui' ** ** Created: Mon Oct 4 19:00:57 2004 ** by: The User Interface Compiler ($Id: mainframe.cpp,v 1.2 2004-10-04 18:45:48 ganovelli Exp $) ** ** WARNING! All changes made in this file will be lost! ****************************************************************************/ #include "mainframe.h" #include #include "myglwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "MainFrame.ui.h" /* * Constructs a MainFrame as a child of 'parent', with the * name 'name' and widget flags set to 'f'. * */ MainFrame::MainFrame( QWidget* parent, const char* name, WFlags fl ) : QMainWindow( parent, name, fl ) { (void)statusBar(); if ( !name ) setName( "MainFrame" ); setCentralWidget( new QWidget( this, "qt_central_widget" ) ); file = new QGroupBox( centralWidget(), "file" ); file->setGeometry( QRect( 70, 0, 90, 80 ) ); OpenButton = new QPushButton( file, "OpenButton" ); OpenButton->setGeometry( QRect( 10, 10, 70, 60 ) ); OpenButton->setPixmap( QPixmap::fromMimeSource( "Open64.png" ) ); buttonGroup1 = new QButtonGroup( centralWidget(), "buttonGroup1" ); buttonGroup1->setGeometry( QRect( 160, 0, 470, 80 ) ); buttonGroup1->setExclusive( TRUE ); BoxButton = new QPushButton( buttonGroup1, "BoxButton" ); BoxButton->setGeometry( QRect( 10, 30, 51, 31 ) ); BoxButton->setToggleButton( TRUE ); WireButton = new QPushButton( buttonGroup1, "WireButton" ); WireButton->setGeometry( QRect( 80, 30, 40, 30 ) ); WireButton->setToggleButton( TRUE ); HiddenButton = new QPushButton( buttonGroup1, "HiddenButton" ); HiddenButton->setGeometry( QRect( 130, 30, 60, 31 ) ); HiddenButton->setToggleButton( TRUE ); FlatWireButton = new QPushButton( buttonGroup1, "FlatWireButton" ); FlatWireButton->setGeometry( QRect( 260, 30, 61, 31 ) ); FlatWireButton->setToggleButton( TRUE ); SmoothButton = new QPushButton( buttonGroup1, "SmoothButton" ); SmoothButton->setGeometry( QRect( 330, 30, 50, 30 ) ); SmoothButton->setToggleButton( TRUE ); SmallTetraButton = new QPushButton( buttonGroup1, "SmallTetraButton" ); SmallTetraButton->setGeometry( QRect( 390, 30, 60, 30 ) ); SmallTetraButton->setToggleButton( TRUE ); FlatButton = new QPushButton( buttonGroup1, "FlatButton" ); FlatButton->setGeometry( QRect( 200, 30, 50, 30 ) ); FlatButton->setToggleButton( TRUE ); FlatButton->setOn( TRUE ); FlatButton->setAutoDefault( FALSE ); FlatButton->setDefault( FALSE ); myGLWidget = new MyGLWidget( centralWidget(), "myGLWidget" ); myGLWidget->setGeometry( QRect( 70, 80, 790, 720 ) ); buttonGroup2 = new QButtonGroup( centralWidget(), "buttonGroup2" ); buttonGroup2->setGeometry( QRect( 630, 0, 230, 80 ) ); buttonGroup2->setExclusive( TRUE ); TrackButton = new QPushButton( buttonGroup2, "TrackButton" ); TrackButton->setGeometry( QRect( 140, 20, 61, 31 ) ); TrackButton->setToggleButton( TRUE ); TrackButton->setOn( TRUE ); TrackButton->setDefault( FALSE ); SectionButton = new QPushButton( buttonGroup2, "SectionButton" ); SectionButton->setGeometry( QRect( 40, 20, 71, 31 ) ); SectionButton->setToggleButton( TRUE ); // actions fileNewAction = new QAction( this, "fileNewAction" ); fileNewAction->setIconSet( QIconSet( QPixmap::fromMimeSource( "" ) ) ); fileOpenAction = new QAction( this, "fileOpenAction" ); fileOpenAction->setToggleAction( FALSE ); fileOpenAction->setOn( FALSE ); fileOpenAction->setIconSet( QIconSet( QPixmap::fromMimeSource( "" ) ) ); fileSaveAction = new QAction( this, "fileSaveAction" ); fileSaveAction->setIconSet( QIconSet( QPixmap::fromMimeSource( "" ) ) ); fileSaveAsAction = new QAction( this, "fileSaveAsAction" ); filePrintAction = new QAction( this, "filePrintAction" ); filePrintAction->setIconSet( QIconSet( QPixmap::fromMimeSource( "" ) ) ); fileExitAction = new QAction( this, "fileExitAction" ); helpContentsAction = new QAction( this, "helpContentsAction" ); helpIndexAction = new QAction( this, "helpIndexAction" ); helpAboutAction = new QAction( this, "helpAboutAction" ); new_menunew_itemAction = new QAction( this, "new_menunew_itemAction" ); infonew_itemAction = new QAction( this, "infonew_itemAction" ); infoSimplexAction = new QAction( this, "infoSimplexAction" ); infoSimplexAction->setToggleAction( TRUE ); infoSimplexAction->setOn( TRUE ); infoQualityAction = new QAction( this, "infoQualityAction" ); infoQualityAction->setToggleAction( TRUE ); infoPhysicsAction = new QAction( this, "infoPhysicsAction" ); infoPhysicsAction->setToggleAction( TRUE ); // toolbars // menubar MenuBar = new QMenuBar( this, "MenuBar" ); File = new QPopupMenu( this ); fileNewAction->addTo( File ); fileOpenAction->addTo( File ); fileSaveAction->addTo( File ); fileSaveAsAction->addTo( File ); File->insertSeparator(); filePrintAction->addTo( File ); File->insertSeparator(); fileExitAction->addTo( File ); MenuBar->insertItem( QString(""), File, 1 ); Help = new QPopupMenu( this ); helpContentsAction->addTo( Help ); helpIndexAction->addTo( Help ); Help->insertSeparator(); helpAboutAction->addTo( Help ); MenuBar->insertItem( QString(""), Help, 2 ); Info_2 = new QPopupMenu( this ); new_menunew_itemAction->addTo( Info_2 ); infoSimplexAction->addTo( Info_2 ); infoQualityAction->addTo( Info_2 ); infoPhysicsAction->addTo( Info_2 ); MenuBar->insertItem( QString(""), Info_2, 3 ); languageChange(); resize( QSize(908, 846).expandedTo(minimumSizeHint()) ); clearWState( WState_Polished ); // signals and slots connections connect( fileNewAction, SIGNAL( activated() ), this, SLOT( fileNew() ) ); connect( fileOpenAction, SIGNAL( activated() ), this, SLOT( fileOpen() ) ); connect( fileSaveAction, SIGNAL( activated() ), this, SLOT( fileSave() ) ); connect( fileSaveAsAction, SIGNAL( activated() ), this, SLOT( fileSaveAs() ) ); connect( helpAboutAction, SIGNAL( activated() ), this, SLOT( helpAbout() ) ); connect( helpContentsAction, SIGNAL( activated() ), this, SLOT( helpContents() ) ); connect( helpIndexAction, SIGNAL( activated() ), this, SLOT( helpIndex() ) ); connect( BoxButton, SIGNAL( pressed() ), myGLWidget, SLOT( setBox() ) ); connect( WireButton, SIGNAL( pressed() ), myGLWidget, SLOT( setWire() ) ); connect( HiddenButton, SIGNAL( pressed() ), myGLWidget, SLOT( setHidden() ) ); connect( FlatButton, SIGNAL( pressed() ), myGLWidget, SLOT( setFlat() ) ); connect( FlatWireButton, SIGNAL( pressed() ), myGLWidget, SLOT( setFlatWire() ) ); connect( SmoothButton, SIGNAL( pressed() ), myGLWidget, SLOT( setSmooth() ) ); connect( SmallTetraButton, SIGNAL( pressed() ), myGLWidget, SLOT( setSmallTetra() ) ); connect( OpenButton, SIGNAL( clicked() ), this, SLOT( fileOpen() ) ); connect( SectionButton, SIGNAL( pressed() ), myGLWidget, SLOT( SectionMouseModality() ) ); connect( TrackButton, SIGNAL( pressed() ), myGLWidget, SLOT( TrackMouseModality() ) ); connect( infoPhysicsAction, SIGNAL( activated() ), myGLWidget, SLOT( SwitchTextPhysics() ) ); connect( infoQualityAction, SIGNAL( activated() ), myGLWidget, SLOT( SwitchTextQuality() ) ); connect( infoSimplexAction, SIGNAL( activated() ), myGLWidget, SLOT( SwitchTextSimplex() ) ); } /* * Destroys the object and frees any allocated resources */ MainFrame::~MainFrame() { // no need to delete child widgets, Qt does it all for us } /* * Sets the strings of the subwidgets using the current * language. */ void MainFrame::languageChange() { setCaption( tr( "TetraView" ) ); file->setTitle( QString::null ); OpenButton->setText( QString::null ); buttonGroup1->setTitle( QString::null ); BoxButton->setText( tr( "box" ) ); WireButton->setText( tr( "Wire" ) ); HiddenButton->setText( tr( "Hidden" ) ); FlatWireButton->setText( tr( "FlatWire" ) ); SmoothButton->setText( tr( "Smooth" ) ); SmallTetraButton->setText( tr( "SmallTetra" ) ); FlatButton->setText( tr( "Flat" ) ); buttonGroup2->setTitle( QString::null ); TrackButton->setText( tr( "Trackball" ) ); SectionButton->setText( tr( "Section" ) ); fileNewAction->setText( tr( "New" ) ); fileNewAction->setMenuText( tr( "&New" ) ); fileNewAction->setAccel( tr( "Ctrl+N" ) ); fileOpenAction->setText( tr( "Open" ) ); fileOpenAction->setMenuText( tr( "&Open..." ) ); fileOpenAction->setAccel( tr( "Ctrl+O" ) ); fileSaveAction->setText( tr( "Save" ) ); fileSaveAction->setMenuText( tr( "&Save" ) ); fileSaveAction->setAccel( tr( "Ctrl+S" ) ); fileSaveAsAction->setText( tr( "Save As" ) ); fileSaveAsAction->setMenuText( tr( "Save &As..." ) ); fileSaveAsAction->setAccel( QString::null ); filePrintAction->setText( tr( "Print" ) ); filePrintAction->setMenuText( tr( "&Print..." ) ); filePrintAction->setAccel( tr( "Ctrl+P" ) ); fileExitAction->setText( tr( "Exit" ) ); fileExitAction->setMenuText( tr( "E&xit" ) ); fileExitAction->setAccel( QString::null ); helpContentsAction->setText( tr( "Contents" ) ); helpContentsAction->setMenuText( tr( "&Contents..." ) ); helpContentsAction->setAccel( QString::null ); helpIndexAction->setText( tr( "Index" ) ); helpIndexAction->setMenuText( tr( "&Index..." ) ); helpIndexAction->setAccel( QString::null ); helpAboutAction->setText( tr( "About" ) ); helpAboutAction->setMenuText( tr( "&About" ) ); helpAboutAction->setAccel( QString::null ); new_menunew_itemAction->setText( QString::null ); new_menunew_itemAction->setMenuText( QString::null ); infonew_itemAction->setText( tr( "new item" ) ); infonew_itemAction->setMenuText( tr( "new item" ) ); infoSimplexAction->setText( tr( "Simplex" ) ); infoSimplexAction->setMenuText( tr( "Simplex" ) ); infoQualityAction->setText( tr( "Quality" ) ); infoQualityAction->setMenuText( tr( "Quality" ) ); infoPhysicsAction->setText( tr( "Physics" ) ); infoPhysicsAction->setMenuText( tr( "Physics" ) ); if (MenuBar->findItem(1)) MenuBar->findItem(1)->setText( tr( "&File" ) ); if (MenuBar->findItem(2)) MenuBar->findItem(2)->setText( tr( "&Help" ) ); if (MenuBar->findItem(3)) MenuBar->findItem(3)->setText( tr( "Info" ) ); } meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/myglwidget.h0000644000175000017500000000545711517500570022171 0ustar gladkgladk#include #include #include #include #include #include "myclasses.h" #include "tetrastats.h" class MyGLWidget: public QGLWidget{ Q_OBJECT private : int _H; int _W; vcg::Trackball Track; vcg::GLWrapTetra *WT; GLdouble projection[16]; GLdouble modelMatrix[16]; GLint viewport[4]; int modality;//rendering modality enum mousemod {MMTrackball, MMSection,MMNavigateSection};//modality of using mouse mousemod mouse_modality; vcg::Trackball TrackClip; /// This are the flags pf info of the mesh that we want to show int _ShowBar; enum { SIMPLEX = 0x00000001, // show vertex number and tetrahedrons number PHYSICS = 0x00000002, // show also physical information about the mesh QUALITY = 0x00000004, // show informations about aspect ratio }; public: MyGLWidget( QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WFlags f = 0 ); virtual void glDraw(); void resizeGL( int w, int h ); virtual void mousePressEvent ( QMouseEvent * e ); virtual void mouseReleaseEvent(QMouseEvent * e ); virtual void mouseMoveEvent ( QMouseEvent * e ); virtual void wheelEvent ( QWheelEvent * e ); virtual void keyPressEvent(QKeyEvent *k); virtual void initializeGL(); virtual void SaveMatrix(); void DrawTetraMesh(); void DrawBox(); bool ShowTextSimplex(); bool ShowTextPhysics(); bool ShowTextQuality(); void DrawTextInfo(); void LoadMatrix(); public slots: ///bounding box visualization modality void setBox(){ modality=0; repaint(); }; ///wireframe modality void setWire(){ modality=1; repaint(); }; ///hiddenlines modality void setHidden(){ modality=2; repaint(); }; ///alternate wire visualization void setFlat(){ modality=3; repaint(); }; ///alternate wire visualization void setFlatWire(){ modality=4; repaint(); }; ///alternate wire visualization void setSmooth(){ modality=5; repaint(); }; ///alternate wire visualization void setSmallTetra() { modality=6; repaint(); }; //set trackball modality void TrackMouseModality() { mouse_modality=MMTrackball; }; //set trackball modality void SectionMouseModality() { mouse_modality=MMSection; }; ///switching to modality of viewing txt info on simplex void SwitchTextSimplex() { if (ShowTextSimplex()) _ShowBar&=~SIMPLEX; else _ShowBar|=SIMPLEX; repaint(); }; ///switching to modality of viewing txt info on physics void SwitchTextPhysics() { if (ShowTextPhysics()) _ShowBar&=~PHYSICS; else _ShowBar|=PHYSICS; repaint(); }; ///switching to modality of viewing txt info on quality void SwitchTextQuality() { if (ShowTextQuality()) _ShowBar&=~QUALITY; else _ShowBar|=QUALITY; repaint(); }; };meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/mainframe.ui.h0000644000175000017500000000245611517500570022364 0ustar gladkgladk/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ #include #include #include extern void openTetraMesh(const char *); void MainFrame::fileNew() { } void MainFrame::fileOpen() { QString filename = QFileDialog::getOpenFileName( "", "Tetrahedral Meshes File (*.ts *.ply)", this, "open file dialog" "Choose a TS Tetrahedral mesh file" ); if (filename!=NULL) { const char *path=filename.ascii(); openTetraMesh(path); } } void MainFrame::fileSave() { } void MainFrame::fileSaveAs() { } void MainFrame::fileExit() { } void MainFrame::helpIndex() { } void MainFrame::helpContents() { } void MainFrame::helpAbout() { } void MainFrame::setWire() { } meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/myglwidget.cpp0000644000175000017500000002114011517500570022507 0ustar gladkgladk#include "myglwidget.h" #include #include #include "mainframe.h" extern MyTetraMesh *tm; extern TetraStats Stats; //extern MainFrame *wp; bool MyGLWidget::ShowTextSimplex() { return (_ShowBar & SIMPLEX); } bool MyGLWidget::ShowTextPhysics() { return (_ShowBar & PHYSICS); } bool MyGLWidget::ShowTextQuality() { return (_ShowBar & QUALITY); } MyGLWidget::MyGLWidget( QWidget * parent, const char * name, const QGLWidget * shareWidget, WFlags f ): QGLWidget(parent, name) { Track.Reset(); Track.radius= 1; WT=0; modality=3; mouse_modality=MMTrackball; _ShowBar=SIMPLEX; grabKeyboard(); } void MyGLWidget::DrawTextInfo() { glPushAttrib(0xffffffff); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); glDisable(GL_CLIP_PLANE0); glColor4d(0.7,0,0.7,0.6); glDepthRange(0.0,0.1); glBegin(GL_QUADS); glVertex3d(-0.5,-0.5,0); glVertex3d(-0.5,-0.3,0); glVertex3d(0.5,-0.3,0); glVertex3d(0.5,-0.5,0); glEnd(); if (Stats.TCurrent()!=0) { glBegin(GL_QUADS); glVertex3d(0.25,0.5,0); glVertex3d(0.5,0.5,0); glVertex3d(0.5,0.2,0); glVertex3d(0.25,0.2,0); glEnd(); } renderText( (width() - 10) / 2, 15, "a" ); QFont f( "arial", 12 ); QFontMetrics fmc( f ); glColor3d(1,1,1); QString str=""; int level=0; glDisable( GL_LIGHTING ); glDisable( GL_TEXTURE_2D ); if (ShowTextSimplex()) { level++; str.sprintf( "Tetrahedrons : %i Vertex: %i ",tm->tn,tm->vn); renderText( 20, height() - level*20, str, f ); } if (ShowTextPhysics()) { level++; str.sprintf( "Volume : %03f ",Stats.volume); renderText( 20, height() - level*20, str, f ); } if (ShowTextQuality()) { level++; str.sprintf( "Aspect Ratio : %03f ",Stats.ratio); renderText( 20, height() - level*20, str, f ); } //at the end i draw the window for informations about a tretrahedron if (Stats.TCurrent()!=0) { str=""; str.sprintf( "Volume : %03f ",Stats.TCurrent()->ComputeVolume()); renderText( width()-150, 30, str, f ); str.sprintf( "Aspect Ratio : %03f ",Stats.TCurrent()->AspectRatio()); renderText( width()-150, 50, str, f ); LoadMatrix(); glColor3d(1,0,0); glDisable(GL_BLEND); //write values of the tetrahedron for (int i=0;i<4;i++) { double x=Stats.TCurrent()->V(i)->P().V(0);//x value of vertex double y=Stats.TCurrent()->V(i)->P().V(1);//y value of vertex double z=Stats.TCurrent()->V(i)->P().V(2);//z value of vertex str.sprintf("%i",i); renderText(x,y,z,str,f); } Stats.TCurrent()->SetS(); } glPopAttrib(); } void MyGLWidget::DrawBox() { glPushAttrib(0xffffffff); glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHT0); glDisable(GL_LIGHTING); glDisable(GL_NORMALIZE); glColor3d(1,1,1); glBegin(GL_LINE_LOOP); glVertex(tm->bbox.P(0)); glVertex(tm->bbox.P(1)); glVertex(tm->bbox.P(3)); glVertex(tm->bbox.P(2)); glEnd(); glBegin(GL_LINE_LOOP); glVertex(tm->bbox.P(4)); glVertex(tm->bbox.P(5)); glVertex(tm->bbox.P(7)); glVertex(tm->bbox.P(6)); glEnd(); glBegin(GL_LINE_LOOP); glVertex(tm->bbox.P(0)); glVertex(tm->bbox.P(1)); glVertex(tm->bbox.P(5)); glVertex(tm->bbox.P(4)); glEnd(); glBegin(GL_LINE_LOOP); glVertex(tm->bbox.P(3)); glVertex(tm->bbox.P(2)); glVertex(tm->bbox.P(6)); glVertex(tm->bbox.P(7)); glEnd(); glPopAttrib(); } void MyGLWidget::DrawTetraMesh() { switch (modality) { case 0:DrawBox();break; case 1:WT->Draw();break; case 2:WT->Draw();break; case 3:WT->Draw();break; case 4:WT->Draw();break; case 5:WT->Draw();break; case 6:WT->Draw();break; } } void MyGLWidget::SaveMatrix() { glGetDoublev(GL_PROJECTION_MATRIX ,projection); glGetDoublev(GL_MODELVIEW_MATRIX ,modelMatrix); } void MyGLWidget::LoadMatrix() { glMatrixMode(GL_PROJECTION); glLoadMatrixd(projection); glMatrixMode(GL_MODELVIEW); glLoadMatrixd(modelMatrix); } void MyGLWidget::glDraw(){ glClearColor(0.2,0.2,0.2,1); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45,1,0.01,20); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,1,0,0,0,0,10,0); if (tm!=0){ glPushMatrix(); glScalef(1/tm->bbox.Diag(),1/tm->bbox.Diag(),1/tm->bbox.Diag()); Track.GetView(); Track.Apply(); Track.Draw(); vcg::Point3d p=tm->bbox.Center(); glTranslate(-p); //if not exist crete an instance of wrapper if (WT==0) { WT= new vcg::GLWrapTetra >(tm->tetra); WT->SetHint(vcg::GLW::HShrinkFactor, 0.8); } /*glGetDoublev(GL_PROJECTION_MATRIX,proj); glGetDoublev(GL_mode_MATRIX,mod); glGetDoublev(GL_PROJECTION_MATRIX,);*/ SaveMatrix(); DrawTetraMesh(); glPopMatrix(); DrawTextInfo(); } QGLWidget::glDraw(); } void MyGLWidget::resizeGL( int w, int h ) { // setup viewport, projection etc.: glMatrixMode (GL_PROJECTION); glLoadIdentity (); float ratio=(float)w/(float)h; gluPerspective(45,ratio,1,20); _W=w; _H=h; glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_MODELVIEW); repaint(); } void MyGLWidget::mousePressEvent ( QMouseEvent * e ) { if (e->button()==Qt::LeftButton) { MyTetraMesh::TetraIterator ti; int face; switch(mouse_modality) { case MMTrackball: Track.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT); break; case MMSection: LoadMatrix(); vcg::GLPickTetra::PickNearestTetraFace(e->x(),_H-e->y(),*tm,ti,face); if (ti!=0) { ///find external face /*while (!ti->IsBorderF(face)) face++;*/ /*ti->SetS();*/ vcg::Point3d p0=ti->V(vcg::Tetra::VofF(face,0))->P(); vcg::Point3d p1=ti->V(vcg::Tetra::VofF(face,1))->P(); vcg::Point3d p2=ti->V(vcg::Tetra::VofF(face,2))->P(); //put the trackball on the barycenter of the face MyTetraMesh::VertexType::CoordType b=(p0+p1+p2)/3.f; WT->AddClipSection(p0,p1,p2); TrackClip.Reset(); TrackClip.radius=1; TrackClip.center.V(0)=(float)b.V(0); TrackClip.center.V(1)=(float)b.V(1); TrackClip.center.V(2)=(float)b.V(2); mouse_modality=MMNavigateSection; TrackClip.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT); } break; case MMNavigateSection: TrackClip.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT); break; } } else if (e->button()==Qt::RightButton) { MyTetraMesh::TetraIterator ti; LoadMatrix(); WT->section.GlClip(); vcg::GLPickTetra::PickNearestTetra(e->x(),_H-e->y(),*tm,ti); if (ti!=0) { Stats.SetTetraInfo(&*ti); } } repaint(); } void MyGLWidget::mouseReleaseEvent(QMouseEvent * e ) { Track.MouseUp(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT); repaint(); } void MyGLWidget::mouseMoveEvent ( QMouseEvent * e ) { if (mouse_modality==MMTrackball) { Track.MouseMove(e->x(),_H-e->y()); repaint(); } else if ((mouse_modality==MMNavigateSection)&&(e->state() & Qt::LeftButton)) { LoadMatrix(); TrackClip.MouseMove(e->x(),_H-e->y()); TrackClip.GetView(); TrackClip.Apply(); WT->section.Transform(TrackClip.track.Matrix()); repaint(); } } void MyGLWidget::wheelEvent ( QWheelEvent * e ){ /* if (mouse_modality==MMTrackball) { const int WHEEL_DELTA =120; Track.MouseWheel( e->delta()/ float(WHEEL_DELTA) ); repaint(); }else*/ if (mouse_modality==MMNavigateSection) { const int WHEEL_DELTA =120; float delta= e->delta()/ float(WHEEL_DELTA); WT->section.Translate(delta/10); ///for casting from double to float TrackClip.center.V(0)=(float)WT->section.P.V(0); TrackClip.center.V(1)=(float)WT->section.P.V(1); TrackClip.center.V(2)=(float)WT->section.P.V(2); repaint(); } } void MyGLWidget::keyPressEvent(QKeyEvent *k) { if (k->key()==Qt::Key_Escape)//&&((mouse_modality==MMNavigateSection)||(mouse_modality==MMSection))) { mouse_modality=MMTrackball; WT->ClearClipSection(); } } void MyGLWidget::initializeGL(){ GLfloat f[4]={0.2,0.2,0.2,1.f}; GLfloat p[4]={3,3,5,0}; glLightfv(GL_LIGHT0, GL_AMBIENT,f); glLightfv(GL_LIGHT1, GL_POSITION,p); glLightfv(GL_LIGHT1, GL_DIFFUSE,f); glLightfv(GL_LIGHT1, GL_SPECULAR,f); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glPolygonMode(GL_FRONT,GL_FILL); glEnable(GL_BACK); glCullFace(GL_BACK); } meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/MainFrame.ui0000644000175000017500000005065111517500570022036 0ustar gladkgladk MainFrame MainFrame 0 0 908 846 TetraView file 70 0 90 80 OpenButton 10 10 70 60 buttonGroup1 160 0 470 80 true BoxButton 10 30 51 31 box true WireButton 80 30 40 30 Wire true HiddenButton 130 30 60 31 Hidden true FlatWireButton 260 30 61 31 FlatWire true SmoothButton 330 30 50 30 Smooth true SmallTetraButton 390 30 60 30 SmallTetra true FlatButton 200 30 50 30 Flat true true false false buttonGroup2 630 0 230 80 true TrackButton 140 20 61 31 Trackball true true false SectionButton 40 20 71 31 Section true myGLWidget 70 70 790 720 MenuBar MyGLWidget
D:/sf/apps/tetraviewer/myglwidget.h
-1 -1 0 5 5 0 0 image0 signal() setBox() setWire() setHidden() setFlat() setFlatWire() setSmallTetra() setSmooth() TrackMouseModality() SectionMouseModality() slot() slot() SwitchTextSimplex() slot() SwitchTextPhysics() slot() SwitchTextQuality()
fileOpenAction false false Open &Open... Ctrl+O fileExitAction Exit E&xit helpContentsAction Contents &Contents... helpIndexAction Index &Index... helpAboutAction About &About new_menunew_itemAction infoSimplexAction true true Simplex Simplex infoQualityAction true Quality Quality infoPhysicsAction true Physics Physics 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154789cad94514c5b5518c77fe7dc4b7b4b6150bb96324418ca32358bee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d6a78d0b027b3cd07d9e68c81c625a6c139408a4384f416100aed6d4b7bdb7b8e0fc0921a70c6ed7b3ae7e43bbff3fffedfc927e2f138bbd1dbdbab7902118fc785d8058f8d8de9aeae2e72b91cb66de338ce7f82e47239666767492412b8aefbf0dcdc553a323242f4501d918e2d3a8f15a9784584100809a609526eafd1a0f54e6142e029c5c21f3ef41583bb77a805efbe1ce9d86279e32619678eaab7853fa0f02a16abb64166ad0cdac75307eb3874b84cb0a14aa5a24108cc0688c48c9a4a1e826ddbe6f0b12219678e8ace610502ccdfafe3f68d3c33bf6c01c59dcc209d472c4e0d35d2f3ba81d205d06005e4de60c77170bd2255af80150870f70e8c0eaf009260a349577714e913a4175d16925b5cbe50607931cc3b677c68ca28a5f7066f5b26f00760febec9e8f032a0e81b68a17fc0201415989647a9d8c4c498cbe8f05f5cff3a4d4bac8bfe210b290b35e01afd428257b1b875cd01aaf4bd1de5dd0fea688e1530ad1c1bab16b7af17393558cf997311c0e49bafd670d6258621f6576c9ab09a3248fe5ae6c08103f49f36517213d33070369bf8e2529ee9c90ceb2b2eef7f14617c2c48722a4b7226845143fa87622905ebeb6514253a9eb5084504a66950c88618bee0303d99217cb09e9ed71a09369538fa523d00e9a50a42eed3bc6d8f41281fa0903e8561796cac86f8f2b33c33930ea0f0fb4d5adbeb30ad22866ffbbad226d2a805d7ee0484220208925aaa50deaa67e27b97e9c90ccdcdf5c462cdd8a94d2e7e62f3603244ea410989a4ed191f52a8fd156b056d9d553a9e0bf0e7ef45c6bf7339fd5e90ec7a88575e6d20d6e6e7e2a755ec854dce7fb8885b2cd014f6f3c2714d3a550bae55ac35c1068fb7061b00b87a7995899b25ce9e0b73e24d8fae97b37c7cbe9370b499fce6066eb54adf6098f6ee2a9a7ff9c70841a5023d270deca510d746537c7e29cdf8ad20475fb4307c82d4fc324ec6859d66fdfc6381e44014b36e9fe6e572393ca54068aa22cfd0598b686b3737aeae90bc9725796f0350802414b6e81b7c9a9f7e70708a2e6e5991cfeee3f1ecec2c0b0b3e8c068142a2a8d23728397132c6dc6f2e2b8b0a8da4b5ddc7f3c735ed47146f0cb4502983693a4c25ca7b83138904fa8a412466e00f48b4271086c2901263676c4a6990b615b6ade15b85694af239984a94585bf6f606bbae5b334f1f37e4a3531e031c8fc7c5a312ff17f849c3e3f1b8f81b8be6900aca9b61c90000000049454e44ae426082 fileOpenAction activated() MainFrame fileOpen() helpAboutAction activated() MainFrame helpAbout() helpContentsAction activated() MainFrame helpContents() helpIndexAction activated() MainFrame helpIndex() BoxButton pressed() myGLWidget setBox() WireButton pressed() myGLWidget setWire() HiddenButton pressed() myGLWidget setHidden() FlatButton pressed() myGLWidget setFlat() FlatWireButton pressed() myGLWidget setFlatWire() SmoothButton pressed() myGLWidget setSmooth() SmallTetraButton pressed() myGLWidget setSmallTetra() OpenButton clicked() MainFrame fileOpen() SectionButton pressed() myGLWidget SectionMouseModality() TrackButton pressed() myGLWidget TrackMouseModality() infoPhysicsAction activated() myGLWidget SwitchTextPhysics() infoQualityAction activated() myGLWidget SwitchTextQuality() infoSimplexAction activated() myGLWidget SwitchTextSimplex() fileExitAction activated() MainFrame close() MainFrame.ui.h fileNew() fileOpen() fileSave() fileSaveAs() fileExit() helpIndex() helpContents() helpAbout() setWire() myglwidget.h
meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/main.cpp0000644000175000017500000000254111517500570021263 0ustar gladkgladk#include #include "mainframe.h" #include #include #include #include #include //#include #include "myglwidget.h" MyTetraMesh TM; MyTetraMesh *tm; TetraStats Stats; typedef vcg::tetra::io::ImporterTS ImpTS; typedef vcg::tetra::UpdateTetraTopology UT; typedef vcg::tetra::UpdateNormals UN; typedef vcg::tetra::UpdateBounding UB; //MainFrame *wp; void openTetraMesh(const char* filename) { //opening the tetrahedral mesh QString path=QString(filename); QString ext =path.right(3); TM=MyTetraMesh(); if (ext==".ts") ImpTS::Open(TM,filename); else vcg::tetra::io::ImporterPLY ::Open(TM,filename); UT::TTTopology(TM.vert,TM.tetra); UT::ClearVTTopology(TM.vert,TM.tetra); UT::VTTopology(TM.vert,TM.tetra); UN::PerVertex(TM); UB::Box(TM); tm=&TM; Stats.SetTetraMesh(tm); Stats.Update(); } int main( int argc, char ** argv ) { tm=0; QApplication a( argc, argv ); MainFrame w; // wp=&w; w.show(); a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) ); return a.exec(); } meshlab-1.3.2+dfsg1/vcglib/apps/tetraviewer/mainframe.h0000644000175000017500000000432411517500570021744 0ustar gladkgladk/**************************************************************************** ** Form interface generated from reading ui file 'MainFrame.ui' ** ** Created: Mon Oct 4 19:00:57 2004 ** by: The User Interface Compiler ($Id: mainframe.h,v 1.1 2004-10-04 18:01:36 ganovelli Exp $) ** ** WARNING! All changes made in this file will be lost! ****************************************************************************/ #ifndef MAINFRAME_H #define MAINFRAME_H #include #include #include class QVBoxLayout; class QHBoxLayout; class QGridLayout; class QSpacerItem; class QAction; class QActionGroup; class QToolBar; class QPopupMenu; class MyGLWidget; class QGroupBox; class QPushButton; class QButtonGroup; class MainFrame : public QMainWindow { Q_OBJECT public: MainFrame( QWidget* parent = 0, const char* name = 0, WFlags fl = WType_TopLevel ); ~MainFrame(); QGroupBox* file; QPushButton* OpenButton; QButtonGroup* buttonGroup1; QPushButton* BoxButton; QPushButton* WireButton; QPushButton* HiddenButton; QPushButton* FlatWireButton; QPushButton* SmoothButton; QPushButton* SmallTetraButton; QPushButton* FlatButton; MyGLWidget* myGLWidget; QButtonGroup* buttonGroup2; QPushButton* TrackButton; QPushButton* SectionButton; QMenuBar *MenuBar; QPopupMenu *File; QPopupMenu *Help; QPopupMenu *Info_2; QAction* fileNewAction; QAction* fileOpenAction; QAction* fileSaveAction; QAction* fileSaveAsAction; QAction* filePrintAction; QAction* fileExitAction; QAction* helpContentsAction; QAction* helpIndexAction; QAction* helpAboutAction; QAction* new_menunew_itemAction; QAction* infonew_itemAction; QAction* infoSimplexAction; QAction* infoQualityAction; QAction* infoPhysicsAction; public slots: virtual void fileNew(); virtual void fileOpen(); virtual void fileSave(); virtual void fileSaveAs(); virtual void fileExit(); virtual void helpIndex(); virtual void helpContents(); virtual void helpAbout(); void setWire(); protected: protected slots: virtual void languageChange(); private: QPixmap image0; }; #endif // MAINFRAME_H meshlab-1.3.2+dfsg1/vcglib/apps/metro/0000755000175000017500000000000012227522351016416 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/metro/mesh_type.h0000644000175000017500000000573411551320500020564 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.6 2005/01/26 22:45:34 cignoni Release 4.04 final updates for gcc compiling issues Revision 1.5 2004/05/14 00:32:36 ganovelli just color and quality on the vertex ****************************************************************************/ #ifndef _CMESH_H #define _CMESH_H #include #include #include // Vertex, Face, Mesh and Grid definitions. #include #include #include #include #include class CFace; class CVertex; struct UsedTypes:public vcg::UsedTypes< vcg::Use::AsFaceType, vcg::Use::AsVertexType>{}; class CVertex : public vcg::Vertex {}; class CFace : public vcg::Face< UsedTypes,vcg::face::VertexRef, vcg::face::Normal3d, vcg::face::EdgePlane,vcg::face::Color4b,vcg::face::Mark,vcg::face::BitFlags> {}; class CMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; #endif meshlab-1.3.2+dfsg1/vcglib/apps/metro/metro.cpp0000644000175000017500000004044611551320500020247 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.23 2007/05/04 16:50:23 ganovelli added plus types version (#ifdef _PLUS_TYPES_ to use it ). Revision 1.22 2006/10/25 12:40:19 fiorin Added possibility to use Octree as search structure: Revision 1.21 2006/05/03 21:22:39 cignoni added missing Include Revision 1.20 2006/04/20 08:30:24 cignoni small GCC compiling issues Revision 1.19 2006/03/27 04:17:07 cignoni moved to generic export.h Revision 1.18 2006/01/10 13:20:40 cignoni Changed ply::PlyMask to io::Mask Revision 1.17 2005/10/02 23:11:00 cignoni Version 4.06, Added possibility of using three different search structures UG Hash and AABB Revision 1.16 2005/09/16 11:52:14 cignoni removed wrong %v in vertex number printing Revision 1.15 2005/04/04 10:36:36 cignoni Release 4.05 Added saving of Error Histogram Revision 1.14 2005/01/26 22:45:34 cignoni Release 4.04 final updates for gcc compiling issues Revision 1.13 2005/01/24 15:46:48 cignoni Release 4.04 Moved to the library core the code for computing min distance froma a point to a mesh using a uniform grid. Slightly faster. Revision 1.12 2005/01/03 11:28:52 cignoni Release 4.03 Better ply compatibility, and improved error reporting Revision 1.11 2004/11/29 09:07:04 cignoni Release 4.02 removed bug in printing Hausdorf distance, removed bug in command line parsing, upgraded import mesh library to support off format Revision 1.10 2004/09/21 23:52:50 cignoni Release 4.01 Revision 1.9 2004/09/20 16:29:08 ponchio Minimal changes. Revision 1.8 2004/09/20 15:17:28 cignoni Removed bug in displays msec and better usage messages Revision 1.7 2004/09/09 22:59:15 cignoni Removed many small warnings Revision 1.6 2004/07/15 00:15:16 cignoni inflate -> offset Revision 1.5 2004/06/24 09:08:31 cignoni Official Release of Metro 4.00 Revision 1.4 2004/05/14 13:53:12 ganovelli GPL added ****************************************************************************/ // ----------------------------------------------------------------------------------------------- // standard libraries #include #include using namespace std; // project definitions. #include "defs.h" #include "sampling.h" #include "mesh_type.h" #include #include #include #include #include #include // ----------------------------------------------------------------------------------------------- using namespace vcg; ////////////////// Command line Flags and parameters bool NumberOfSamples = false; bool SamplesPerAreaUnit = false; bool CleaningFlag=false; // ----------------------------------------------------------------------------------------------- void Usage() { printf("\nUsage: "\ "metro file1 file2 [opt]\n"\ "Where opt can be:\n"\ " -v disable vertex sampling\n"\ " -e disable edge sampling\n"\ " -f disable face sampling\n"\ " -u ignore unreferred vertices\n"\ " -sx set the face sampling mode\n"\ " where x can be:\n"\ " -s0 montecarlo sampling\n"\ " -s1 subdivision sampling\n"\ " -s2 similar triangles sampling (Default)\n"\ " -n# set the required number of samples (overrides -A)\n"\ " -a# set the required number of samples per area unit (overrides -N)\n"\ " -c save a mesh with error as per-vertex colour and quality\n"\ " -C # # Set the min/max values used for color mapping\n"\ " -L Remove duplicated and unreferenced vertices before processing\n"\ " -h write files with histograms of error distribution\n"\ " -G Use a static Uniform Grid as Search Structure (default)\n"\ " -O Use an octree as a Search Structure\n"\ " -A Use an AxisAligned Bounding Box Tree as Search Structure\n"\ " -H Use an Hashed Uniform Grid as Search Structure\n"\ "\n" "Default options are to sample vertexes, edge and faces by taking \n" "a number of samples that is approx. 10x the face number.\n" ); exit(-1); } // simple aux function that compute the name for the file containing the stored computations std::string SaveFileName(const std::string &filename) { int pos=filename.find_last_of('.',filename.length()); std::string fileout=filename.substr(0,pos)+"_metro.ply"; return fileout; } // Open Mesh void OpenMesh(const char *filename, CMesh &m) { int err = tri::io::Importer::Open(m,filename); if(err) { printf("Error in reading %s: '%s'\n",filename,tri::io::Importer::ErrorMsg(err)); if(tri::io::Importer::ErrorCritical(err)) exit(-1); } printf("read mesh `%s'\n", filename); if(CleaningFlag){ int dup = tri::Clean::RemoveDuplicateVertex(m); int unref = tri::Clean::RemoveUnreferencedVertex(m); printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,filename); } } int main(int argc, char**argv) { CMesh S1, S2; float ColorMin=0, ColorMax=0; double dist1_max, dist2_max; unsigned long n_samples_target, elapsed_time; double n_samples_per_area_unit; int flags; // print program info printf("-------------------------------\n" " Metro V.4.07 \n" " http://vcg.isti.cnr.it\n" " release date: "__DATE__"\n" "-------------------------------\n\n"); if(argc <= 2) Usage(); // default parameters flags = SamplingFlags::VERTEX_SAMPLING | SamplingFlags::EDGE_SAMPLING | SamplingFlags::FACE_SAMPLING | SamplingFlags::SIMILAR_SAMPLING; // parse command line. for(int i=3; i < argc;) { if(argv[i][0]=='-') switch(argv[i][1]) { case 'h' : flags |= SamplingFlags::HIST; break; case 'v' : flags &= ~SamplingFlags::VERTEX_SAMPLING; break; case 'e' : flags &= ~SamplingFlags::EDGE_SAMPLING; break; case 'f' : flags &= ~SamplingFlags::FACE_SAMPLING; break; case 'u' : flags |= SamplingFlags::INCLUDE_UNREFERENCED_VERTICES; break; case 's' : switch(argv[i][2]) { case '0': flags = (flags | SamplingFlags::MONTECARLO_SAMPLING ) & (~ SamplingFlags::NO_SAMPLING );break; case '1': flags = (flags | SamplingFlags::SUBDIVISION_SAMPLING ) & (~ SamplingFlags::NO_SAMPLING );break; case '2': flags = (flags | SamplingFlags::SIMILAR_SAMPLING ) & (~ SamplingFlags::NO_SAMPLING );break; default : printf(MSG_ERR_INVALID_OPTION, argv[i]); exit(0); } break; case 'n': NumberOfSamples = true; n_samples_target = (unsigned long) atoi(&(argv[i][2])); break; case 'a': SamplesPerAreaUnit = true; n_samples_per_area_unit = (unsigned long) atoi(&(argv[i][2])); break; case 'c': flags |= SamplingFlags::SAVE_ERROR; break; case 'L': CleaningFlag=true; break; case 'C': ColorMin=float(atof(argv[i+1])); ColorMax=float(atof(argv[i+2])); i+=2; break; case 'A': flags |= SamplingFlags::USE_AABB_TREE; printf("Using AABB Tree as search structure\n"); break; case 'G': flags |= SamplingFlags::USE_STATIC_GRID; printf("Using static uniform grid as search structure\n"); break; case 'H': flags |= SamplingFlags::USE_HASH_GRID; printf("Using hashed uniform grid as search structure\n"); break; case 'O': flags |= SamplingFlags::USE_OCTREE; printf("Using octree as search structure\n"); break; default : printf(MSG_ERR_INVALID_OPTION, argv[i]); exit(0); } i++; } if(!(flags & SamplingFlags::USE_HASH_GRID) && !(flags & SamplingFlags::USE_AABB_TREE) && !(flags & SamplingFlags::USE_OCTREE)) flags |= SamplingFlags::USE_STATIC_GRID; // load input meshes. OpenMesh(argv[1],S1); OpenMesh(argv[2],S2); string S1NewName=SaveFileName(argv[1]); string S2NewName=SaveFileName(argv[2]); if(!NumberOfSamples && !SamplesPerAreaUnit) { NumberOfSamples = true; n_samples_target = 10 * max(S1.fn,S2.fn);// take 10 samples per face } // compute face information tri::UpdateEdges::Set(S1); tri::UpdateEdges::Set(S2); // set bounding boxes for S1 and S2 tri::UpdateBounding::Box(S1); tri::UpdateBounding::Box(S2); // set Bounding Box. Box3 bbox, tmp_bbox_M1=S1.bbox, tmp_bbox_M2=S2.bbox; bbox.Add(S1.bbox); bbox.Add(S2.bbox); bbox.Offset(bbox.Diag()*0.02); S1.bbox = bbox; S2.bbox = bbox; // initialize time info. int t0=clock(); Sampling ForwardSampling(S1,S2); Sampling BackwardSampling(S2,S1); // print mesh info. printf("Mesh info:\n"); printf(" M1: '%s'\n\tvertices %7i\n\tfaces %7i\n\tarea %12.4f\n", argv[1], S1.vn, S1.fn, ForwardSampling.GetArea()); printf("\tbbox (%7.4f %7.4f %7.4f)-(%7.4f %7.4f %7.4f)\n", tmp_bbox_M1.min[0], tmp_bbox_M1.min[1], tmp_bbox_M1.min[2], tmp_bbox_M1.max[0], tmp_bbox_M1.max[1], tmp_bbox_M1.max[2]); printf("\tbbox diagonal %f\n", (float)tmp_bbox_M1.Diag()); printf(" M2: '%s'\n\tvertices %7i\n\tfaces %7i\n\tarea %12.4f\n", argv[2], S2.vn, S2.fn, BackwardSampling.GetArea()); printf("\tbbox (%7.4f %7.4f %7.4f)-(%7.4f %7.4f %7.4f)\n", tmp_bbox_M2.min[0], tmp_bbox_M2.min[1], tmp_bbox_M2.min[2], tmp_bbox_M2.max[0], tmp_bbox_M2.max[1], tmp_bbox_M2.max[2]); printf("\tbbox diagonal %f\n", (float)tmp_bbox_M2.Diag()); // Forward distance. printf("\nForward distance (M1 -> M2):\n"); ForwardSampling.SetFlags(flags); if(NumberOfSamples) { ForwardSampling.SetSamplesTarget(n_samples_target); n_samples_per_area_unit = ForwardSampling.GetNSamplesPerAreaUnit(); } else { ForwardSampling.SetSamplesPerAreaUnit(n_samples_per_area_unit); n_samples_target = ForwardSampling.GetNSamplesTarget(); } printf("target # samples : %u\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit); ForwardSampling.Hausdorff(); dist1_max = ForwardSampling.GetDistMax(); printf("\ndistances:\n max : %f (%f wrt bounding box diagonal)\n", (float)dist1_max, (float)dist1_max/bbox.Diag()); printf(" mean : %f\n", ForwardSampling.GetDistMean()); printf(" RMS : %f\n", ForwardSampling.GetDistRMS()); printf("# vertex samples %9d\n", ForwardSampling.GetNVertexSamples()); printf("# edge samples %9d\n", ForwardSampling.GetNEdgeSamples()); printf("# area samples %9d\n", ForwardSampling.GetNAreaSamples()); printf("# total samples %9d\n", ForwardSampling.GetNSamples()); printf("# samples per area unit: %f\n\n", ForwardSampling.GetNSamplesPerAreaUnit()); // Backward distance. printf("\nBackward distance (M2 -> M1):\n"); BackwardSampling.SetFlags(flags); if(NumberOfSamples) { BackwardSampling.SetSamplesTarget(n_samples_target); n_samples_per_area_unit = BackwardSampling.GetNSamplesPerAreaUnit(); } else { BackwardSampling.SetSamplesPerAreaUnit(n_samples_per_area_unit); n_samples_target = BackwardSampling.GetNSamplesTarget(); } printf("target # samples : %u\ntarget # samples/area : %f\n", n_samples_target, n_samples_per_area_unit); BackwardSampling.Hausdorff(); dist2_max = BackwardSampling.GetDistMax(); printf("\ndistances:\n max : %f (%f wrt bounding box diagonal)\n", (float)dist2_max, (float)dist2_max/bbox.Diag()); printf(" mean : %f\n", BackwardSampling.GetDistMean()); printf(" RMS : %f\n", BackwardSampling.GetDistRMS()); printf("# vertex samples %9d\n", BackwardSampling.GetNVertexSamples()); printf("# edge samples %9d\n", BackwardSampling.GetNEdgeSamples()); printf("# area samples %9d\n", BackwardSampling.GetNAreaSamples()); printf("# total samples %9d\n", BackwardSampling.GetNSamples()); printf("# samples per area unit: %f\n\n", BackwardSampling.GetNSamplesPerAreaUnit()); // compute time info. elapsed_time = clock() - t0; int n_total_sample=ForwardSampling.GetNSamples()+BackwardSampling.GetNSamples(); double mesh_dist_max = max(dist1_max , dist2_max); printf("\nHausdorff distance: %f (%f wrt bounding box diagonal)\n",(float)mesh_dist_max,(float)mesh_dist_max/bbox.Diag()); printf(" Computation time : %d ms\n",(int)(1000.0*elapsed_time/CLOCKS_PER_SEC)); printf(" # samples/second : %f\n\n", (float)n_total_sample/((float)elapsed_time/CLOCKS_PER_SEC)); // save error files. if(flags & SamplingFlags::SAVE_ERROR) { vcg::tri::io::PlyInfo p; p.mask|=vcg::tri::io::Mask::IOM_VERTCOLOR | vcg::tri::io::Mask::IOM_VERTQUALITY /* | vcg::ply::PLYMask::PM_VERTQUALITY*/ ; //p.mask|=vcg::ply::PLYMask::PM_VERTCOLOR|vcg::ply::PLYMask::PM_VERTQUALITY; if(ColorMax!=0 || ColorMin != 0){ vcg::tri::UpdateColor::VertexQualityRamp(S1,ColorMin,ColorMax); vcg::tri::UpdateColor::VertexQualityRamp(S2,ColorMin,ColorMax); } tri::io::ExporterPLY::Save( S1,S1NewName.c_str(),true,p); tri::io::ExporterPLY::Save( S2,S2NewName.c_str(),true,p); } // save error files. if(flags & SamplingFlags::HIST) { ForwardSampling.GetHist().FileWrite("forward_result.csv"); BackwardSampling.GetHist().FileWrite("backward_result.csv"); } return 0; } // ----------------------------------------------------------------------------------------------- meshlab-1.3.2+dfsg1/vcglib/apps/metro/metro.pro0000644000175000017500000000043311517500570020266 0ustar gladkgladk TARGET = metro LIBPATH += DEPENDPATH += . INCLUDEPATH += . ../.. CONFIG += console stl TEMPLATE = app HEADERS += defs.h sampling.h mesh_type.h SOURCES += metro.cpp ../../wrap/ply/plylib.cpp # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundle meshlab-1.3.2+dfsg1/vcglib/apps/metro/sampling.h0000644000175000017500000005676411551320500020412 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.24 2007/05/04 16:50:23 ganovelli added plus types version (#ifdef _PLUS_TYPES_ to use it ). Revision 1.23 2006/10/25 12:40:19 fiorin Added possibility to use Octree as search structure: Revision 1.22 2006/04/20 08:30:24 cignoni small GCC compiling issues Revision 1.21 2006/01/22 10:05:43 cignoni Corrected use of Area with the unambiguous DoubleArea Revision 1.20 2005/11/12 06:44:29 cignoni Changed GetClosest -> GetClosestFace Revision 1.19 2005/10/02 23:11:50 cignoni Changed the core for distance computation. Current version uses the lib flexible search structures. Now the comparison can be done exploiting a static uniform grid, a hashed grid or a hierarchy of AA box. Revision 1.18 2005/09/16 11:55:18 cignoni Partial adding of AABB trees, still not working... Revision 1.17 2005/08/26 10:42:47 cignoni Added scalar type specification in the typedef of MetroMeshGrid Revision 1.16 2005/04/04 10:47:26 cignoni Release 4.05 Added saving of Error Histogram Revision 1.15 2005/01/26 22:45:34 cignoni Release 4.04 final updates for gcc compiling issues Revision 1.14 2005/01/24 15:37:14 cignoni updated from MinDistPoint to Closest (and removed some warnings) Revision 1.13 2004/09/20 16:17:46 ponchio Floating except fixed (happened on meshes with less than 100 faces :P) Revision 1.12 2004/09/09 22:59:15 cignoni Removed many small warnings Revision 1.11 2004/08/25 15:28:15 ponchio Comma at end of enum. Revision 1.10 2004/08/25 15:15:22 ganovelli minor changes to comply gcc compiler (typename's and stuff) Revision 1.9 2004/07/18 10:13:34 cignoni NewUserBit -> NewBitFlag Revision 1.8 2004/06/24 09:08:31 cignoni Official Release of Metro 4.00 Revision 1.7 2004/05/14 13:49:07 ganovelli created Revision 1.6 2004/05/14 00:38:01 ganovelli a bit of cleaning: SamplingFlags struct added optional treatment for unreferred vertices. Note: unref vertices are tested against unref vertices without using the grid...it is n^2 with n number of unreferred vertices. To make it with the grid in the proper way : derive face and vertex from a simplexClass, instantiate GridStaticPtr on the simplexClass template. ****************************************************************************/ #ifndef __VCGLIB__SAMPLING #define __VCGLIB__SAMPLING #include //#include "min_dist_point.h" #include #include #include #include #include #include #include #include #include #include namespace vcg { struct SamplingFlags{ enum{ HIST = 0x0001, VERTEX_SAMPLING = 0x0002, EDGE_SAMPLING = 0x0004, FACE_SAMPLING = 0x0008, MONTECARLO_SAMPLING = 0x0010, SUBDIVISION_SAMPLING = 0x0020, SIMILAR_SAMPLING = 0x0040, NO_SAMPLING = 0x0070, SAVE_ERROR = 0x0100, INCLUDE_UNREFERENCED_VERTICES = 0x0200, USE_STATIC_GRID = 0x0400, USE_HASH_GRID = 0x0800, USE_AABB_TREE = 0x1000, USE_OCTREE = 0x2000 }; }; // ----------------------------------------------------------------------------------------------- template class Sampling { public: private: typedef typename MetroMesh::CoordType CoordType; typedef typename MetroMesh::ScalarType ScalarType; typedef typename MetroMesh::VertexType VertexType; typedef typename MetroMesh::VertexPointer VertexPointer; typedef typename MetroMesh::VertexIterator VertexIterator; typedef typename MetroMesh::FaceIterator FaceIterator; typedef typename MetroMesh::FaceType FaceType; typedef typename MetroMesh::FaceContainer FaceContainer; typedef GridStaticPtr MetroMeshGrid; typedef SpatialHashTable MetroMeshHash; typedef AABBBinaryTreeIndex MetroMeshAABB; typedef Octree MetroMeshOctree; typedef Point3 Point3x; // data structures MetroMesh &S1; MetroMesh &S2; MetroMeshGrid gS2; MetroMeshHash hS2; MetroMeshAABB tS2; MetroMeshOctree oS2; unsigned int n_samples_per_face ; float n_samples_edge_to_face_ratio ; float bbox_factor ; float inflate_percentage ; unsigned int min_size ; int n_hist_bins ; int print_every_n_elements ; int referredBit ; // parameters double dist_upper_bound; double n_samples_per_area_unit; unsigned long n_samples_target; int Flags; // results Histogram hist; unsigned long n_total_samples; unsigned long n_total_area_samples; unsigned long n_total_edge_samples; unsigned long n_total_vertex_samples; double max_dist; double mean_dist; double RMS_dist; double volume; double area_S1; // globals int n_samples; // private methods inline double ComputeMeshArea(MetroMesh & mesh); float AddSample(const Point3x &p); inline void AddRandomSample(FaceIterator &T); inline void SampleEdge(const Point3x & v0, const Point3x & v1, int n_samples_per_edge); void VertexSampling(); void EdgeSampling(); void FaceSubdiv(const Point3x & v0, const Point3x &v1, const Point3x & v2, int maxdepth); void SimilarTriangles(const Point3x &v0, const Point3x &v1, const Point3x &v2, int n_samples_per_edge); void MontecarloFaceSampling(); void SubdivFaceSampling(); void SimilarFaceSampling(); public : // public methods Sampling(MetroMesh &_s1, MetroMesh &_s2); ~Sampling(); void Hausdorff(); double GetArea() {return area_S1;} double GetDistMax() {return max_dist;} double GetDistMean() {return mean_dist;} double GetDistRMS() {return RMS_dist;} double GetDistVolume() {return volume;} unsigned long GetNSamples() {return n_total_samples;} unsigned long GetNAreaSamples() {return n_total_area_samples;} unsigned long GetNEdgeSamples() {return n_total_edge_samples;} unsigned long GetNVertexSamples() {return n_total_vertex_samples;} double GetNSamplesPerAreaUnit() {return n_samples_per_area_unit;} unsigned long GetNSamplesTarget() {return n_samples_target;} Histogram &GetHist() {return hist;} void SetFlags(int flags) {Flags = flags;} void ClearFlag(int flag) {Flags &= (flag ^ -1);} void SetParam(double _n_samp) {n_samples_target = _n_samp;} void SetSamplesTarget(unsigned long _n_samp); void SetSamplesPerAreaUnit(double _n_samp); }; // ----------------------------------------------------------------------------------------------- // constructor template Sampling::Sampling(MetroMesh &_s1, MetroMesh &_s2):S1(_s1),S2(_s2) { Flags = 0; area_S1 = ComputeMeshArea(_s1); // set default numbers n_samples_per_face = 10; n_samples_edge_to_face_ratio = 0.1f; bbox_factor = 0.1f; inflate_percentage = 0.02f; min_size = 125; /* 125 = 5^3 */ n_hist_bins = 256; print_every_n_elements = S1.fn/100; if(print_every_n_elements <= 1) print_every_n_elements = 2; referredBit = VertexType::NewBitFlag(); // store the unreferred vertices FaceIterator fi; VertexIterator vi; int i; for(fi = _s1.face.begin(); fi!= _s1.face.end(); ++fi) for(i=0;i<3;++i) (*fi).V(i)->SetUserBit(referredBit); } template Sampling::~Sampling() { VertexType::DeleteBitFlag(referredBit); } // set sampling parameters template void Sampling::SetSamplesTarget(unsigned long _n_samp) { n_samples_target = _n_samp; n_samples_per_area_unit = n_samples_target / (double)area_S1; } template void Sampling::SetSamplesPerAreaUnit(double _n_samp) { n_samples_per_area_unit = _n_samp; n_samples_target = (unsigned long)((double) n_samples_per_area_unit * area_S1); } // auxiliary functions template inline double Sampling::ComputeMeshArea(MetroMesh & mesh) { FaceIterator face; double area = 0.0; for(face=mesh.face.begin(); face != mesh.face.end(); face++) if(!(*face).IsD()) area += DoubleArea(*face); return area/2.0; } template float Sampling::AddSample(const Point3x &p ) { FaceType *f=0; Point3x normf, bestq, ip; ScalarType dist; dist = dist_upper_bound; // compute distance between p_i and the mesh S2 if(Flags & SamplingFlags::USE_AABB_TREE) f=tri::GetClosestFace(S2, tS2, p, dist_upper_bound, dist, normf, bestq, ip); if(Flags & SamplingFlags::USE_HASH_GRID) f=tri::GetClosestFace(S2, hS2, p, dist_upper_bound, dist, normf, bestq, ip); if(Flags & SamplingFlags::USE_STATIC_GRID) f=tri::GetClosestFace(S2, gS2, p, dist_upper_bound, dist, normf, bestq, ip); if (Flags & SamplingFlags::USE_OCTREE) f=tri::GetClosestFace(S2, oS2, p, dist_upper_bound, dist, normf, bestq, ip); // update distance measures if(dist == dist_upper_bound) return -1.0; if(dist > max_dist) max_dist = dist; // L_inf mean_dist += dist; // L_1 RMS_dist += dist*dist; // L_2 n_total_samples++; if(Flags & SamplingFlags::HIST) hist.Add((float)fabs(dist)); return (float)dist; } // ----------------------------------------------------------------------------------------------- // --- Vertex Sampling --------------------------------------------------------------------------- template void Sampling::VertexSampling() { // Vertex sampling. int cnt = 0; float error; printf("Vertex sampling\n"); VertexIterator vi; typename std::vector::iterator vif; for(vi=S1.vert.begin();vi!=S1.vert.end();++vi) if( (*vi).IsUserBit(referredBit) || // it is referred ((Flags&SamplingFlags::INCLUDE_UNREFERENCED_VERTICES) != 0) ) //include also unreferred { error = AddSample((*vi).cP()); n_total_vertex_samples++; // save vertex quality if(Flags & SamplingFlags::SAVE_ERROR) (*vi).Q() = error; // print progress information if(!(++cnt % print_every_n_elements)) printf("Sampling vertices %d%%\r", (100 * cnt/S1.vn)); } printf(" \r"); } // ----------------------------------------------------------------------------------------------- // --- Edge Sampling ----------------------------------------------------------------------------- template inline void Sampling::SampleEdge(const Point3x & v0, const Point3x & v1, int n_samples_per_edge) { // uniform sampling of the segment v0v1. Point3x e((v1-v0)/(double)(n_samples_per_edge+1)); int i; for(i=1; i <= n_samples_per_edge; i++) { AddSample(v0 + e*i); n_total_edge_samples++; } } template void Sampling::EdgeSampling() { // Edge sampling. typedef std::pair pvv; std::vector< pvv > Edges; printf("Edge sampling\n"); // compute edge list. FaceIterator fi; for(fi=S1.face.begin(); fi != S1.face.end(); fi++) for(int i=0; i<3; ++i) { Edges.push_back(make_pair((*fi).V0(i),(*fi).V1(i))); if(Edges.back().first > Edges.back().second) swap(Edges.back().first, Edges.back().second); } sort(Edges.begin(), Edges.end()); typename std::vector< pvv>::iterator edgeend = unique(Edges.begin(), Edges.end()); Edges.resize(edgeend-Edges.begin()); // sample edges. typename std::vector::iterator ei; double n_samples_per_length_unit; double n_samples_decimal = 0.0; int cnt=0; if(Flags & SamplingFlags::FACE_SAMPLING) n_samples_per_length_unit = sqrt((double)n_samples_per_area_unit); else n_samples_per_length_unit = n_samples_per_area_unit; for(ei=Edges.begin(); ei!=Edges.end(); ++ei) { n_samples_decimal += Distance((*ei).first->cP(),(*ei).second->cP()) * n_samples_per_length_unit; n_samples = (int) n_samples_decimal; SampleEdge((*ei).first->cP(), (*ei).second->cP(), (int) n_samples); n_samples_decimal -= (double) n_samples; // print progress information if(!(++cnt % print_every_n_elements)) printf("Sampling edge %d%%\r", (100 * cnt/Edges.size())); } printf(" \r"); } // ----------------------------------------------------------------------------------------------- // --- Face Sampling ----------------------------------------------------------------------------- // Montecarlo sampling. template inline void Sampling::AddRandomSample(FaceIterator &T) { // random sampling over the input face. double rnd_1, rnd_2; // vertices of the face T. Point3x p0(T->V(0)->cP()); Point3x p1(T->V(1)->cP()); Point3x p2(T->V(2)->cP()); // calculate two edges of T. Point3x v1(p1 - p0); Point3x v2(p2 - p0); // choose two random numbers. rnd_1 = (double)rand() / (double)RAND_MAX; rnd_2 = (double)rand() / (double)RAND_MAX; if(rnd_1 + rnd_2 > 1.0) { rnd_1 = 1.0 - rnd_1; rnd_2 = 1.0 - rnd_2; } // add a random point on the face T. AddSample (p0 + (v1 * rnd_1 + v2 * rnd_2)); n_total_area_samples++; } template void Sampling::MontecarloFaceSampling() { // Montecarlo sampling. int cnt = 0; double n_samples_decimal = 0.0; FaceIterator fi; srand(clock()); // printf("Montecarlo face sampling\n"); for(fi=S1.face.begin(); fi != S1.face.end(); fi++) if(!(*fi).IsD()) { // compute # samples in the current face. n_samples_decimal += 0.5*DoubleArea(*fi) * n_samples_per_area_unit; n_samples = (int) n_samples_decimal; // for every sample p_i in T... for(int i=0; i < n_samples; i++) AddRandomSample(fi); n_samples_decimal -= (double) n_samples; // print progress information // if(!(++cnt % print_every_n_elements)) // printf("Sampling face %d%%\r", (100 * cnt/S1.fn)); } // printf(" \r"); } // Subdivision sampling. template void Sampling::FaceSubdiv(const Point3x & v0, const Point3x & v1, const Point3x & v2, int maxdepth) { // recursive face subdivision. if(maxdepth == 0) { // ground case. AddSample((v0+v1+v2)/3.0f); n_total_area_samples++; n_samples++; return; } // compute the longest edge. double maxd01 = SquaredDistance(v0,v1); double maxd12 = SquaredDistance(v1,v2); double maxd20 = SquaredDistance(v2,v0); int res; if(maxd01 > maxd12) if(maxd01 > maxd20) res = 0; else res = 2; else if(maxd12 > maxd20) res = 1; else res = 2; // break the input triangle along the median to the the longest edge. Point3x pp; switch(res) { case 0 : pp = (v0+v1)/2; FaceSubdiv(v0,pp,v2,maxdepth-1); FaceSubdiv(pp,v1,v2,maxdepth-1); break; case 1 : pp = (v1+v2)/2; FaceSubdiv(v0,v1,pp,maxdepth-1); FaceSubdiv(v0,pp,v2,maxdepth-1); break; case 2 : pp = (v2+v0)/2; FaceSubdiv(v0,v1,pp,maxdepth-1); FaceSubdiv(pp,v1,v2,maxdepth-1); break; } } template void Sampling::SubdivFaceSampling() { // Subdivision sampling. int cnt = 0, maxdepth; double n_samples_decimal = 0.0; typename MetroMesh::FaceIterator fi; printf("Subdivision face sampling\n"); for(fi=S1.face.begin(); fi != S1.face.end(); fi++) { // compute # samples in the current face. n_samples_decimal += 0.5*DoubleArea(*fi) * n_samples_per_area_unit; n_samples = (int) n_samples_decimal; if(n_samples) { // face sampling. maxdepth = ((int)(log((double)n_samples)/log(2.0))); n_samples = 0; FaceSubdiv((*fi).V(0)->cP(), (*fi).V(1)->cP(), (*fi).V(2)->cP(), maxdepth); } n_samples_decimal -= (double) n_samples; // print progress information if(!(++cnt % print_every_n_elements)) printf("Sampling face %d%%\r", (100 * cnt/S1.fn)); } printf(" \r"); } // Similar Triangles sampling. template void Sampling::SimilarTriangles(const Point3x & v0, const Point3x & v1, const Point3x & v2, int n_samples_per_edge) { Point3x V1((v1-v0)/(double)(n_samples_per_edge-1)); Point3x V2((v2-v0)/(double)(n_samples_per_edge-1)); int i, j; // face sampling. for(i=1; i < n_samples_per_edge-1; i++) for(j=1; j < n_samples_per_edge-1-i; j++) { AddSample( v0 + (V1*(double)i + V2*(double)j) ); n_total_area_samples++; n_samples++; } } template void Sampling::SimilarFaceSampling() { // Similar Triangles sampling. int cnt = 0, n_samples_per_edge; double n_samples_decimal = 0.0; FaceIterator fi; printf("Similar Triangles face sampling\n"); for(fi=S1.face.begin(); fi != S1.face.end(); fi++) { // compute # samples in the current face. n_samples_decimal += 0.5*DoubleArea(*fi) * n_samples_per_area_unit; n_samples = (int) n_samples_decimal; if(n_samples) { // face sampling. n_samples_per_edge = (int)((sqrt(1.0+8.0*(double)n_samples) +5.0)/2.0); n_samples = 0; SimilarTriangles((*fi).V(0)->cP(), (*fi).V(1)->cP(), (*fi).V(2)->cP(), n_samples_per_edge); } n_samples_decimal -= (double) n_samples; // print progress information if(!(++cnt % print_every_n_elements)) printf("Sampling face %d%%\r", (100 * cnt/S1.fn)); } printf(" \r"); } // ----------------------------------------------------------------------------------------------- // --- Distance ---------------------------------------------------------------------------------- template void Sampling::Hausdorff() { Box3< ScalarType> bbox; typedef typename std::vector::iterator FaceVecIterator; // set grid meshes. if(Flags & SamplingFlags::USE_HASH_GRID) hS2.Set(S2.face.begin(),S2.face.end()); if(Flags & SamplingFlags::USE_AABB_TREE) tS2.Set(S2.face.begin(),S2.face.end()); if(Flags & SamplingFlags::USE_STATIC_GRID) gS2.Set(S2.face.begin(),S2.face.end()); if(Flags & SamplingFlags::USE_OCTREE) oS2.Set(S2.face.begin(),S2.face.end()); // set bounding box bbox = S2.bbox; dist_upper_bound = /*bbox_factor * */bbox.Diag(); if(Flags & SamplingFlags::HIST) hist.SetRange(0.0, dist_upper_bound/100.0, n_hist_bins); // initialize sampling statistics. n_total_area_samples = n_total_edge_samples = n_total_vertex_samples = n_total_samples = n_samples = 0; max_dist = -HUGE_VAL; mean_dist = RMS_dist = 0; // Vertex sampling. if(Flags & SamplingFlags::VERTEX_SAMPLING) VertexSampling(); // Edge sampling. if(n_samples_target > n_total_samples) { n_samples_target -= (int) n_total_samples; n_samples_per_area_unit = n_samples_target / area_S1; if(Flags & SamplingFlags::EDGE_SAMPLING) { EdgeSampling(); if(n_samples_target > n_total_samples) n_samples_target -= (int) n_total_samples; else n_samples_target=0; } // Face sampling. if((Flags & SamplingFlags::FACE_SAMPLING) && (n_samples_target > 0)) { n_samples_per_area_unit = n_samples_target / area_S1; if(Flags & SamplingFlags::MONTECARLO_SAMPLING) MontecarloFaceSampling(); if(Flags & SamplingFlags::SUBDIVISION_SAMPLING) SubdivFaceSampling(); if(Flags & SamplingFlags::SIMILAR_SAMPLING) SimilarFaceSampling(); } } // compute vertex colour if(Flags & SamplingFlags::SAVE_ERROR) vcg::tri::UpdateColor::VertexQualityRamp(S1); // compute statistics n_samples_per_area_unit = (double) n_total_samples / area_S1; volume = mean_dist / n_samples_per_area_unit / 2.0; mean_dist /= n_total_samples; RMS_dist = sqrt(RMS_dist / n_total_samples); } } #endif meshlab-1.3.2+dfsg1/vcglib/apps/metro/defs.h0000644000175000017500000000206311517500570017511 0ustar gladkgladk// ----------------------------------------------------------------------------------------------- #ifndef _DEFS_H #define _DEFS_H // ----------------------------------------------------------------------------------------------- // error messages #define MSG_ERR_MESH_LOAD "error loading the input meshes.\n" #define MSG_ERR_INVALID_OPTION "unable to parse option '%s'\n" #define MSG_ERR_FILE_OPEN "unable to open the output file.'n" #define MSG_ERR_UNKNOWN_FORMAT "unknown file format '%s'.\n" // global constants #define NO_SAMPLES_PER_FACE 10 #define N_SAMPLES_EDGE_TO_FACE_RATIO 0.1 #define BBOX_FACTOR 0.1 #define INFLATE_PERCENTAGE 0.02 #define MIN_SIZE 125 /* 125 = 5^3 */ #define N_HIST_BINS 256 #define PRINT_EVERY_N_ELEMENTS 1000 // ----------------------------------------------------------------------------------------------- #endif // ----------------------------------------------------------------------------------------------- meshlab-1.3.2+dfsg1/vcglib/apps/metro/history.txt0000644000175000017500000000277411517500570020672 0ustar gladkgladk VCGLib http://vcg.sf.net o o Visual and Computer Graphics Library o o _ O _ Copyright(C) 2005-2006 \/)\/ Visual Computing Lab http://vcg.isti.cnr.it /\/| ISTI - Italian National Research Council | \ Metro 4.07 2007/05/11 All rights reserved. 2007/05/11 Release 4.07 Added support for obj files. Now the Distance comparison can be done exploiting also a (slow) octree. Removed bug on the display of the area of the mesh. 2005/10/03 Release 4.06 Changed the core for distance computation. Current version uses the lib flexible search structures. Now the comparison can be done exploiting a static uniform grid, a hashed grid or a hierarchy of AA box. 2005/04/04 Release 4.05 Added saving of Error Histogram 2005/01/26 Release 4.04 Gcc compiling issues Moved to the library core the code for computing min distance froma a point to a mesh using a uniform grid. Slightly faster. 2005/01/03 Release 4.03 Better ply compatibility, and improved error reporting 2004/11/29 Release 4.02 removed bug in printing Hausdorf distance, removed bug in command line parsing, upgraded import mesh library to support off format meshlab-1.3.2+dfsg1/vcglib/apps/metro/readme.txt0000644000175000017500000001220011517500570020407 0ustar gladkgladk VCGLib http://vcg.sf.net o o Visual and Computer Graphics Library o o _ O _ Copyright(C) 2005-2006 \/)\/ Visual Computing Lab http://vcg.isti.cnr.it /\/| ISTI - Italian National Research Council | \ Metro 4.07 2007/05/11 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. --- Synopsis --- Metro is a tool designed to evaluate the difference between two triangular meshes. Metro adopts an approximated approach based on surface sampling and point-to-surface distance computation. Please, when using this tool, cite the following reference: P. Cignoni, C. Rocchini and R. Scopigno "Metro: measuring error on simplified surfaces" Computer Graphics Forum, Blackwell Publishers, vol. 17(2), June 1998, pp 167-174 Available at http://vcg.sf.net You can find some sample mesh to test in the 'Metro Sample dataset' package downloadable from sourceforge. For any question about this software please contact: Paolo Cignoni ( p.cignoni@isti.cnr.it ) --- General Info --- Metro is a tool designed to evaluate the difference between two triangular meshes. Metro adopts an approximated approach based on surface sampling and point-to-surface distance computation. Three different surface sampling methods are implemented: * Montecarlo sampling (pick k random samples in the interior of each face) * Subdivision sampling (recursively subdivide each face along the longest edge and choose the sample in the center of each cell) * Similar Triangles sampling (subdivide each face F in k polygons similar to F and sample the face in correspondence with the vertices of these polygons, internal to F) Note that the three methods described above are used to sample only the interior of each face. A different scheme is used to sample vertices and edges: vertices are sampled in the straightforward manner, while edges are sampled by uniformly interleaving samples along each edge. Three different Spatial indexing structures can be used to find the closest point to a sample, a Statically Allocated Uniform Grid, a Hashed Uniform Grid and a Hierarchy of axis aligned bounding boxes. --- Basic usage --- Metro is a command-line tool which allows the user to select among different sampling schemes. A list of the command-line parameters accepted by the tool is shown in the following. Usage: Metro file1 file2 [opts] where "file1" and "file2" are the input meshes in PLY, OFF or STL format, and opts can be: -v disable vertex sampling -e disable edge sampling -f disable face sampling -u ignore unreferred vertices -sx set the face sampling mode where x can be: -s0 montecarlo sampling -s1 subdivision sampling -s2 similar triangles sampling (Default) -n# set the required number of samples (overrides -A) -a# set the required number of samples per area unit (overrides -N) -c save a mesh with error as per-vertex colour and quality -C # # Set the min/max values used for color mapping -L Remove duplicated and unreferenced vertices before processing -h write files with histograms of error distribution -G Use a static Uniform Grid as Search Structure (default) -A Use an Axis Aligned Bounding Box Tree as Search Structure -H Use an Hashed Uniform Grid as Search Structure -O Use an Octree as Search Structure The -C option is useful in combination with -c option for creating a set of meshes with a coherent coloring scheme. It sets how the errors are mapped into color according to the following formula, let e be the error and ColorRamp be a R->RGB function mapping 0..1 values into a smooth RedYellowGreenCyanBlue ramp: e=Clamp(e,min,max); VertexColor = ColorRamp( (e-min)/(max-min) ); The Histogram files saved by the -h option contains two column of numbers e_i and p_i; p_i denotes the fraction of the surface having an error between e_i and e_{i+1}. The sum of the second column values should give 1.meshlab-1.3.2+dfsg1/vcglib/apps/ptx2ply/0000755000175000017500000000000012227522351016712 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/apps/ptx2ply/ptx2ply.cpp0000644000175000017500000004665311551320500021045 0ustar gladkgladk#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace vcg; class MyEdge; class MyFaceC; class MyFace; class MyVertexC : public VertexSimp2 {}; class MyFaceC : public FaceSimp2< MyVertexC,MyEdge,MyFaceC,face::VertexRef, face::Normal3f,face::BitFlags> {}; class MyMeshC : public tri::TriMesh< std::vector, std::vector > {}; class MyVertex : public VertexSimp2 {}; class MyFace : public FaceSimp2< MyVertex,MyEdge,MyFace,face::VertexRef, face::Normal3f,face::BitFlags> {}; class MyMesh : public tri::TriMesh< std::vector, std::vector > {}; using namespace std; using namespace tri; /* class MyEdge; class MyFace; class MyEdgeC; class MyFaceC; class MyVertexC:public VertexVCVN{}; class MyFaceC :public FaceFN{}; class MyMeshC: public tri::TriMesh< std::vector, std::vector >{}; class MyVertex:public VertexVN{}; class MyFace :public FaceFN{}; class MyMesh: public tri::TriMesh< std::vector, std::vector >{}; */ //------------------------------------------------------- int nummeshes; // number of meshes extracted so far MyMesh currentmesh; // current mesh, read from stream and saved one completed MyMeshC currentmeshC; // current mesh, read from stream and saved one completed Matrix44f currtrasf; float angle; // angle treshold for face deletion int singlemap; // single map mode, which map is to be saved. if -1 then all map are saved int frommap; // skip all maps BEFORE this index int tomap; // skip all maps AFTER this index bool savecolor; // if has color, save it on 3dmesh bool hascolor; // true if the current mesh has color bool saveall; // all elements are keeped (even invalids) bool flipfaces; // flip all faces int todump; bool dumpit; bool unpack; bool onlypoints; // store only points bool switchside; // inverse triangulation order (swaping row->cols) // read the current mesh from the stream int readmesh(FILE* fp) { int colnum; int rownum; int trinum; int numtokens; int rit,cit; char linebuf[256]; int ii; float xx,yy,zz; // position float rr,gg,bb; // color float rf; // reflectance MyMesh::FaceIterator fi; MyMesh::VertexIterator vi; MyMeshC::FaceIterator fiC; MyMeshC::VertexIterator viC; // cleaning mesh currentmesh.Clear(); currentmeshC.Clear(); // getting mesh size; fscanf(fp,"%i\n",&colnum); fscanf(fp,"%i\n",&rownum); // initial 4 lines [still don't know what is this :) :)] fscanf(fp,"%f %f %f\n", &xx, &yy, &zz); fscanf(fp,"%f %f %f\n", &xx, &yy, &zz); fscanf(fp,"%f %f %f\n", &xx, &yy, &zz); fscanf(fp,"%f %f %f\n", &xx, &yy, &zz); // now the transformation matrix fscanf(fp,"%f %f %f %f\n", &(currtrasf.ElementAt(0,0)), &(currtrasf.ElementAt(0,1)), &(currtrasf.ElementAt(0,2)), &(currtrasf.ElementAt(0,3))); fscanf(fp,"%f %f %f %f\n", &(currtrasf.ElementAt(1,0)), &(currtrasf.ElementAt(1,1)), &(currtrasf.ElementAt(1,2)), &(currtrasf.ElementAt(1,3))); fscanf(fp,"%f %f %f %f\n", &(currtrasf.ElementAt(2,0)), &(currtrasf.ElementAt(2,1)), &(currtrasf.ElementAt(2,2)), &(currtrasf.ElementAt(2,3))); fscanf(fp,"%f %f %f %f\n", &(currtrasf.ElementAt(3,0)), &(currtrasf.ElementAt(3,1)), &(currtrasf.ElementAt(3,2)), &(currtrasf.ElementAt(3,3))); // now the real data begins // first line, we should know if the format is // XX YY ZZ RF // or it is // XX YY ZZ RF RR GG BB // read the entire first line and then count the spaces. it's rude but it works :) ii=0; fread(&(linebuf[ii++]),1,1,fp); while(linebuf[ii-1] != '\n') fread(&(linebuf[ii++]),1,1,fp); linebuf[ii-1] = '\0'; // terminate the string numtokens=1; for(ii=0; ii::AddVertices(currentmeshC,(rownum*colnum)); } else { vi = Allocator::AddVertices(currentmesh,(rownum*colnum)); } // parse the first line.... if(hascolor) { printf("\n hascolor "); sscanf(linebuf,"%f %f %f %f %f %f %f", &xx, &yy, &zz, &rf, &rr, &gg, &bb); } else { printf("\n no color "); sscanf(linebuf,"%f %f %f %f", &xx, &yy, &zz, &rf); } //addthefirstpoint if(hascolor && savecolor) { (*viC).P()[0]=xx; (*viC).P()[1]=yy; (*viC).P()[2]=zz; (*viC).Q()=rf; (*viC).C()[0]=rr; (*viC).C()[1]=gg; (*viC).C()[2]=bb; viC++; } else { (*vi).P()[0]=xx; (*vi).P()[1]=yy; (*vi).P()[2]=zz; vi++; } // now for each line until end of mesh (row*col)-1 for(ii=0; ii<((rownum*colnum)-1); ii++) { // read the stream if(hascolor) fscanf(fp,"%f %f %f %f %f %f %f", &xx, &yy, &zz, &rf, &rr, &gg, &bb); else fscanf(fp,"%f %f %f %f", &xx, &yy, &zz, &rf); // add the point if(hascolor && savecolor) { (*viC).P()[0]=xx; (*viC).P()[1]=yy; (*viC).P()[2]=zz; (*viC).Q()=rf; (*viC).C()[0]=rr; (*viC).C()[1]=gg; (*viC).C()[2]=bb; viC++; } else { (*vi).P()[0]=xx; (*vi).P()[1]=yy; (*vi).P()[2]=zz; vi++; } } currentmesh.vn = currentmesh.vert.size(); if(! onlypoints) { // now i can triangulate trinum = (rownum-1) * (colnum-1) * 2; if(hascolor && savecolor) { fiC= Allocator::AddFaces(currentmeshC,trinum); } else { fi= Allocator::AddFaces(currentmesh,trinum); } currentmesh.fn = 0; currentmeshC.fn = 0; int v0i,v1i,v2i; for(rit=0; ritIsD()) || ((*fiC).V(1)->IsD()) || ((*fiC).V(2)->IsD()) ) { (*fiC).SetD(); currentmeshC.fn--; } } else for(fi = currentmesh.face.begin(); fi != currentmesh.face.end(); fi++) { if( ((*fi).V(0)->IsD()) || ((*fi).V(1)->IsD()) || ((*fi).V(2)->IsD()) ) { (*fi).SetD(); currentmesh.fn--; } } } if(hascolor && savecolor) printf("V: %8i F: %8i \n", currentmeshC.vn, currentmeshC.fn); else printf("V: %8i F: %8i \n", currentmesh.vn, currentmesh.fn); // eliminate high angle triangles if((angle != 90)&&(!saveall)) { printf(" culling by angle \n"); float limit = cos( angle*3.14159265358979323846/180.0 ); Point3f raggio; if(hascolor && savecolor) { tri::UpdateNormals::PerFaceNormalized(currentmeshC); for(fiC = currentmeshC.face.begin(); fiC != currentmeshC.face.end(); fiC++) if(!(*fiC).IsD()) { raggio = -((*fiC).V(0)->P() + (*fiC).V(1)->P() + (*fiC).V(2)->P()) / 3.0; raggio.Normalize(); if(((*fiC).N() * raggio) < limit) { (*fiC).SetD(); currentmeshC.fn--; } } } else { vcg::tri::UpdateNormals::PerFaceNormalized(currentmesh); for(fi = currentmesh.face.begin(); fi != currentmesh.face.end(); fi++) if(!(*fi).IsD()) { raggio = -((*fi).V(0)->P() + (*fi).V(1)->P() + (*fi).V(2)->P()) / 3.0; raggio.Normalize(); if((raggio * (*fi).N()) < limit) { (*fi).SetD(); currentmesh.fn--; } } } } } currtrasf.transposeInPlace(); // apply tranformation if(hascolor && savecolor) { for(viC = currentmeshC.vert.begin(); viC != currentmeshC.vert.end(); viC++) if(!(*viC).IsD()) { (*viC).P() = currtrasf * (*viC).P(); } } else { for(vi = currentmesh.vert.begin(); vi != currentmesh.vert.end(); vi++) if(!(*vi).IsD()) { (*vi).P() = currtrasf * (*vi).P(); } } if(hascolor && savecolor) { int dup = tri::Clean::RemoveDuplicateVertex(currentmeshC); if(! onlypoints) int unref = tri::Clean::RemoveUnreferencedVertex(currentmeshC); } else { int dup = tri::Clean::RemoveDuplicateVertex(currentmesh); if(! onlypoints) int unref = tri::Clean::RemoveUnreferencedVertex(currentmesh); } return 0; } // save each mesh in a separate file void dounpack(FILE* fp) { FILE* outf; char namef[128]; int rnum; char linebuf[256]; int ii; bool trovato; rnum=1; trovato = false; // search for the first integer while(!trovato) { // read the entire first line and then count the spaces. it's rude but it works :) ii=0; fread(&(linebuf[ii++]),1,1,fp); while(linebuf[ii-1] != '\n') fread(&(linebuf[ii++]),1,1,fp); linebuf[ii-1] = '\0'; // terminate the string //check the string if(strchr(linebuf,' ') == NULL) trovato = true; } while(!feof(fp)) { sprintf(namef,"range%03i.ptx",rnum++); outf = fopen(namef,"w"); // write first integer fprintf(outf,"%s\n",linebuf); // read and write next int ii=0; fread(&(linebuf[ii++]),1,1,fp); while(linebuf[ii-1] != '\n') fread(&(linebuf[ii++]),1,1,fp); linebuf[ii-1] = '\0'; // terminate the string fprintf(outf,"%s\n",linebuf); // search for the next integer while(!trovato) { // read the entire first line and then count the spaces. it's rude but it works :) ii=0; fread(&(linebuf[ii++]),1,1,fp); while(linebuf[ii-1] != '\n') fread(&(linebuf[ii++]),1,1,fp); linebuf[ii-1] = '\0'; // terminate the string //if not an integer then write it, otherwise close and remember for next step if(strchr(linebuf,' ') == NULL) trovato = true; else fprintf(outf,"%s\n",linebuf); } fclose(outf); } } // skip a mesh int skipmesh(FILE* fp) { int colnum; int rownum; int skiplines; char linebuf; if(feof(fp)) return -1; // getting mesh size; fscanf(fp,"%i\n",&colnum); fscanf(fp,"%i\n",&rownum); printf("\n %i x %i \n", rownum, colnum); printf(" expect V %i F %i\n",(rownum*colnum),((rownum-1)*(colnum-1)*2)); if(feof(fp)) return -1; skiplines = (colnum * rownum) + 8; // have to skip (col * row) lines plus 8 lines for the header for(int ii=0; ii AA are removed \n"); printf(" default is no cut. \n"); printf(" beware! this only works for range maps that still need \n"); printf(" to be tranformed in the final reference system \n"); printf(" (in this case the viewpoint is the origin) \n"); printf("\n"); printf("-c save color if present \n"); printf("\n"); printf("-mNN extract just the map NN, skip all the rest of the file \n"); printf("\n"); printf("-fNN extract maps starting FROM index NN \n"); printf("\n"); printf("-tNN extract maps UP TO index NN \n"); printf("\n"); printf("-u unpack the file generating a ptx for each map \n"); printf("\n"); printf("-k keep all elements (no points/tris discarded) \n"); printf(" only useful for debug \n"); printf("\n"); printf("-f flip all faces \n"); printf("\n"); printf("-p store points only \n"); printf("\n"); printf("-r during triangulation, swap rows->columns \n"); printf("\n"); printf("MESH INDICES STARTS FROM 1 \n"); printf("parameters -f and -t can be used together to specify an index\n"); printf("range to be processed. \n"); printf("-------------------------------------------------------------\n"); exit(0); } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// int main(int argc, char *argv[]) { FILE *fp; char filename[256]; char modelname[128]; //--------------------------------------------------------------- printf("PTX to PLY conversion\n"); //--------------------------------------------------------------- //-- init params nummeshes = 1; currentmesh.Clear(); angle = 90.0; singlemap = -1; frommap = 0; tomap = 99999; todump = 1024; dumpit = false; unpack = false; savecolor = false; saveall = false; flipfaces = false; onlypoints = false; switchside = false; if(argc < 2) printhelp(); //-- parseparams(argc, argv); strcpy(modelname,argv[1]); modelname[strlen(argv[1])-4] = '\0'; fp = fopen(argv[1],"r"); if(unpack) dounpack(fp); while((!feof(fp)) && (nummeshes <= tomap)) { printf("mesh %3i ",nummeshes); if((nummeshes >= frommap) && (nummeshes <= tomap) && ((singlemap == -1) || (singlemap == nummeshes))) { if(dumpit) { FILE* outf; char cbuf; outf = fopen("dump.txt","w"); for(int dit=0; dit::Save(currentmeshC,filename, plyMask); } else tri::io::ExporterPLY::Save(currentmesh,filename); } printf("ok! \n"); } else { printf("skipping "); skipmesh(fp); printf("ok! \n"); } nummeshes++; } fclose(fp); return 0; } meshlab-1.3.2+dfsg1/vcglib/apps/ptx2ply/ptx2ply.pro0000644000175000017500000000043611517500570021061 0ustar gladkgladk TARGET = ptx2ply LIBPATH += DEPENDPATH += . INCLUDEPATH += . ../.. CONFIG += console stl TEMPLATE = app #HEADERS += defs.h sampling.h mesh_type.h SOURCES += ptx2ply.cpp ../../wrap/ply/plylib.cpp # Mac specific Config required to avoid to make application bundles CONFIG -= app_bundlemeshlab-1.3.2+dfsg1/vcglib/wrap/0000755000175000017500000000000012227522351015276 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/wrap/gui/0000755000175000017500000000000012227522351016062 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/wrap/gui/rubberband.h0000644000175000017500000001063511517500603020343 0ustar gladkgladk/**************************************************************************** * 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.1 2008/02/16 12:00:34 benedetti first version, adapted from meshlab's editmeasure plugin ****************************************************************************/ #ifndef RUBBERBAND_H #define RUBBERBAND_H #include #include namespace vcg { /*! @brief The Rubberband class. This class is useful for interactively draw a straight line between 2 pickable points in a GL widget. */ class Rubberband { public: //data: /// The color of the rubberband Color4b color; // functions: /*! @brief The constructor. Initialize the rubberband data. */ Rubberband(Color4b); /*! @brief The destructor. The destructor. */ virtual ~Rubberband() {} /*! @brief Render the rubberband and do the picking. Is important that this function is called in order to apply the Drag and Pin commands. @param glw the GL widget. */ void Render(QGLWidget* glw); /*! @brief Set the current rubberband endpoint. This function should be called after MouseMove events. @param cursor the cursor position. */ void Drag(QPoint cursor); /*! @brief Ask for picking. This function should be called after MouseRelease events. The first time is called, if the picking is successful, sets the startpoint. The second time sets, if the picking is successful, the endpoint. After the second time this has no effect. @param cursor the cursor position. */ void Pin(QPoint cursor); /*! @brief Reset the rubberband. */ void Reset(); /*! @brief Return true if the rubberband has been drawn. @return true if the line has been drawn, false otherwise. */ bool IsReady(); /*! @brief Get the rubberband start and end points. @param startpoint is set to the rubberband start point. @param endpoint is set to the rubberband end point. @warning Don't call this function until IsReady() returns true! */ void GetPoints(Point3f &startpoint,Point3f &endpoint); /*! @brief Render a text label near the endpoint (if it exists). @param text the text to render. @param glw the GL widget. */ void RenderLabel(QString text,QGLWidget* glw); 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*/ meshlab-1.3.2+dfsg1/vcglib/wrap/gui/trackutils.h0000644000175000017500000011015111732414757020431 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.13 2008/02/26 18:46:55 ponchio Fixed bug in drawing position of the trackball when changin center. Revision 1.12 2008/02/24 18:10:54 ponchio Fixed scale behaviour. Revision 1.11 2008/02/24 18:05:08 ponchio Should work as before. I didn't test cylinder and other exotic modes. Revision 1.10 2008/02/24 14:37:00 ponchio Restored trackball functionality. Not very much tested, and code will need some cleanup. Revision 1.9 2008/02/22 18:57:47 benedetti first attempt to correct after quaternion ToMatrix() inversion (does not work yet) Revision 1.8 2008/02/15 20:54:45 benedetti removed some variable initialization related warning Revision 1.7 2007/10/22 14:39:54 cignoni corrected bug into the drawsphere (thanks to nico and guido!) Revision 1.6 2007/08/17 09:19:40 cignoni glEnable (GL_LINE_SMOOTH) should go before changing the linewidth. Revision 1.5 2007/07/14 12:44:40 benedetti Minor edits in Doxygen documentation. Revision 1.4 2007/07/09 22:41:22 benedetti Added Doxygen documentation, removed using namespace std, some other minor changes. Revision 1.3 2007/06/12 08:58:08 benedetti Minor fix in DrawUglyCylinderMode() Revision 1.2 2007/05/28 08:10:47 fiorin Removed type cast warnings Revision 1.1 2007/05/15 14:57:34 benedetti Utility functions for the trackmodes, first version ****************************************************************************/ #ifndef TRACKUTILS_H #define TRACKUTILS_H #include #include #include #include #include #include #include #include #include #include using namespace std; namespace vcg { /*! @brief This namespace contains some support functions used by TrackMode subclassess. \warning Many of these functions shouldn't be here and are supposed to be moved to some appropriate place by the library administrator. \warning The \e DrawUgly series of functions is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... */ namespace trackutils { /*! @brief Compute the plane perpedicular to view dir and passing through the manipulator center. @param camera the camera of the manipulator. @param center the center of the manipulator. @return the plane perpedicular to view dir and passing through the manipulator center. */ Plane3f GetViewPlane (const View < float >&camera, const Point3f & center) { Point3f vp = camera.ViewPoint (); Plane3f pl; Point3f plnorm = vp - center; plnorm.Normalize(); pl.Set(plnorm, plnorm.dot(center)); return pl; } /*! @brief Convert a line to a normalized ray. @param l the line to be converted. @return the normalized ray. */ Ray3f line2ray(const Line3f &l){ Ray3f r(l.Origin(),l.Direction()); r.Normalize(); return r; } /*! @brief Project a window coordinate point on the plane perpedicular to view dir and passing through the manipulator center. @param tb the manipulator. @param p the window coordinate point. @return p's projection on plane perpedicular to view dir and passing through the manipulator center. */ Point3f HitViewPlane (Trackball * tb, const Point3f & p) { Plane3f vp = GetViewPlane (tb->camera, tb->center); Line3fN ln = tb->camera.ViewLineFromWindow (Point3f (p[0], p[1], 0)); Point3f PonVP; IntersectionPlaneLine < float >(vp, ln, PonVP); return PonVP; } // nota: non ho scritto io questa funzione, // quindi la documentazione doxy potrebbe non essere accurata al 100%. /*! @brief Project a window coordinate point on the rotational hyperboloid relative to the manipulator.
The original documentation (in italian) follows:
dato un punto in coordinate di schermo e.g. in pixel stile opengl 
calcola il punto di intersezione tra la viewline  che passa per 
viewpoint e per hitplane e l'iperboloide.
l'iperboloide si assume essere quello di rotazione attorno alla 
retta viewpoint-center e di raggio rad
si assume come sistema di riferimento quello con l'origine 
su center ecome x la retta center-viewpoint

eq linea
       hitplane.y
y = - ----------- * x + hitplane.y 
      viewpoint.x

eq hiperboloide di raggio r (e.g. che passa per (r/sqrt2,r/sqrt2) 

     1
y = --- * (r^2 /2.0)
     x 

 hitplane.y
 ----------- * x^2 - hitplane.y *x + (r^2/2.0) == 0
 viewpoint.x
@param center the center of the manipulator. @param radius the radius of the manipulator. @param viewpoint the view point. @param vp the view plane. @param hitplane the projection of the window coordinate point on the view plane. @param hit the projection of hitplane on the rotational hyperboloid relative to the manipulator. @return true if and only if hit is valid. */ bool HitHyper (Point3f center, float radius, Point3f viewpoint, Plane3f vp, Point3f hitplane, Point3f & hit) { float hitplaney = Distance (center, hitplane); float viewpointx = Distance (center, viewpoint); float a = hitplaney / viewpointx; float b = -hitplaney; float c = radius * radius / 2.0f; float delta = b * b - 4 * a * c; float x1, x2, xval, yval; if (delta > 0) { x1 = (-b - sqrt (delta)) / (2.0f * a); x2 = (-b + sqrt (delta)) / (2.0f * a); xval = x1; // always take the minimum value solution yval = c / xval; // alternatively it also could be the other part of the equation yval=-(hitplaney/viewpointx)*xval+hitplaney; } else { return false; } // Computing the result in 3d space; Point3f dirRadial = hitplane - center; dirRadial.Normalize (); Point3f dirView = vp.Direction (); dirView.Normalize (); hit = center + dirRadial * yval + dirView * xval; return true; } // nota: non ho scritto io questa funzione, // quindi la documentazione doxy potrebbe non essere accurata al 100%. /*! @brief Project a window coordinate point on the sphere relative to the manipulator.
The original documentation (in italian) follows:
dato un punto in coordinate di schermo e.g. in pixel stile opengl 
restituisce un punto in coordinate di mondo sulla superficie 
della trackball.
La superficie della trackball e' data da una sfera + una porzione 
di iperboloide di rotazione.
Assumiamo la sfera di raggio unitario e centrata sull'origine e 
di guardare lungo la y negativa.

                                    X   0   sqrt(1/2)  1  
eq sfera:              y=sqrt(1-x*x);   1   sqrt(1/2)  0   
eq iperboloide :       y=1/2*x;         inf  sqrt(1/2)  1/2
eq cono                y=x+sqrt(2);
@param tb the manipulator. @param p the window coordinate point. @return the projection of p on the sphere relative to the manipulator. */ Point3f HitSphere (Trackball * tb, const Point3f & p) { Point3f center = tb->center; Line3fN ln = tb->camera.ViewLineFromWindow (Point3f (p[0], p[1], 0)); Plane3f vp = GetViewPlane (tb->camera, center); Point3f hitPlane(0,0,0), //intersection view plane with point touched hitSphere(0,0,0), hitSphere1(0,0,0), hitSphere2(0,0,0), hitHyper(0,0,0); IntersectionPlaneLine < float >(vp, ln, hitPlane); Sphere3f sphere (center, tb->radius);//trackball sphere bool resSp = IntersectionLineSphere < float >(sphere, ln, hitSphere1, hitSphere2); Point3f viewpoint = tb->camera.ViewPoint (); if (resSp == true) { if (Distance (viewpoint, hitSphere1) < Distance (viewpoint, hitSphere2)) hitSphere = hitSphere1; else hitSphere = hitSphere2; } /*float dl= */ Distance (ln, center); bool resHp = HitHyper (center, tb->radius, viewpoint, vp, hitPlane, hitHyper); // four cases // 1) Degenerate line tangent to both sphere and hyperboloid! if ((!resSp && !resHp)) { Point3f hit = ClosestPoint (ln, center); //printf("closest point to line %f\n",Distance(hit,tb->center)); return hit; } if ((resSp && !resHp)) return hitSphere; // 2) line cross only the sphere if ((!resSp && resHp)) return hitHyper; // 3) line cross only the hyperboloid // 4) line cross both sphere and hyperboloid: choose according angle. float angleDeg = math::ToDeg (Angle ((viewpoint - center), (hitSphere - center))); //printf("Angle %f (%5.2f %5.2f %5.2f) (%5.2f %5.2f %5.2f)\n",angleDeg,hitSphere[0],hitSphere[1],hitSphere[2],hitHyper[0],hitHyper[1],hitHyper[2]); if (angleDeg < 45) return hitSphere; else return hitHyper; // Codice ORIGINALE PONCHIO //vp.SetOffset(vp.Offset() + Thr); //Point3f hit; //bool res = Intersection(vp, ln, hit); //float d = Distance(tb->center - vn.Direction()*Thr, hit); //if(d < Thr) { // Point3f hit2; // Sphere3f sphere(tb->center, tb->radius); // bool res = Intersection(sphere, ln, hit, hit2); // //find closest intersection to sphere // float d = (hit - viewpoint).Norm(); // float d2 = (hit2 - viewpoint).Norm(); // if(d > d2) hit = hit2; // hit -= tb->center; //} else { // if(d > 2.99 * Thr) // d = 2.99 * Thr; // Point3f norm = (hit - tb->center)^(viewpoint - tb->center); // norm.Normalize(); // float phi = -M_PI/4 - 3*M_PI/8 *(d - Thr)/Thr; // Quaternionf q(phi, norm); // hit = q.Rotate((viewpoint - tb->center).Normalize() * tb->radius); //} // hit.Normalize(); // return hit; } /*! @brief Calculates the minimal distance between 2 lines. P and Q are the lines, P_s and Q_t are set to be the closest points on these lines. it's returned the distance from P_s and Q_t, and a boolean value which is true if the lines are parallel enough. if P and Q are parallel P_s and Q_t aren't set. the formula is taken from pages 81-83 of "Eric Lengyel - Mathematics for 3D Game Programming & Computer Graphics" @param P the first line. @param Q the second line. @param P_s the point on P closest to Q. @param Q_t the point on Q closest to P. @return a std::pair made with the distance from P_s to Q_t and a boolean value, true if and only if P and Q are almost parallel. */ std::pair< float, bool > LineLineDistance(const Line3f & P,const Line3f & Q,Point3f & P_s, Point3f & Q_t){ Point3f p0 = P.Origin (), Vp = P.Direction (); Point3f q0 = Q.Origin (), Vq = Q.Direction (); float VPVP = Vp.dot(Vp); float VQVQ = Vq.dot(Vq); float VPVQ = Vp.dot(Vq); const float det = ( VPVP * VQVQ ) - ( VPVQ * VPVQ ); const float EPSILON = 0.00001f; if ( fabs(det) < EPSILON ) { return std::make_pair(Distance(P,q0), true); } float b1= (q0 - p0).dot(Vp); float b2= (p0 - q0).dot(Vq); float s = ( (VQVQ * b1) + (VPVQ * b2) ) / det; float t = ( (VPVQ * b1) + (VPVP * b2) ) / det; P_s = p0 + (Vp * s); Q_t = q0 + (Vq * t); return std::make_pair(Distance(P_s,Q_t),false); } /*! @brief Calculates the minimal distance between a ray and a line. R is the ray and Q is the line, R_s and Q_t are set to be the closest points on the ray and the line. it's returned the distance from R_s and Q_t, and a boolean value which is true if the ray and the line are parallel enough. if R and Q are parallel R_s and Q_t aren't set. @param R the ray. @param Q the line. @param R_s the point on R closest to Q. @param Q_t the point on Q closest to R. @return a std::pair made with the distance from R_s to Q_t and a boolean value, true if and only if P and Q are almost parallel. */ std::pair< float, bool > RayLineDistance(const Ray3f & R,const Line3f & Q,Point3f & R_s, Point3f & Q_t){ Point3f r0 = R.Origin (), Vr = R.Direction (); Point3f q0 = Q.Origin (), Vq = Q.Direction (); float VRVR = Vr.dot(Vr); float VQVQ = Vq.dot(Vq); float VRVQ = Vr.dot(Vq); const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ ); const float EPSILON = 0.00001f; if ( ( det >= 0.0f ? det : -det) < EPSILON ) { return std::make_pair(Distance(Q,r0), true); } float b1= (q0 - r0).dot(Vr); float b2= (r0 - q0).dot(Vq); float s = ( (VQVQ * b1) + (VRVQ * b2) ) / det; float t = ( (VRVQ * b1) + (VRVR * b2) ) / det; if(s<0){ R_s = r0; Q_t = ClosestPoint(Q,R_s); }else { R_s = r0 + (Vr * s); Q_t = q0 + (Vq * t); } return std::make_pair(Distance(R_s,Q_t),false); } ///*! // @brief Calculates the minimal distance between 2 segments. // // R e Q are the segments, R_s and Q_t are set to be the closest points on // the segments. // // it's returned the distance from R_s and Q_t, and a boolean value which is true // if the segments are parallel enough. // @param R the first segment. // @param Q the second segment. // @param R_s the point on R closest to Q. // @param Q_t the point on Q closest to R. // @return a std::pair made with the distance from R_s to Q_t and a boolean value, true if and only if P and Q are almost parallel. //*/ //std::pair< float, bool > SegmentSegmentDistance(const Segment3f & R, const Segment3f & Q, Point3f & R_s, Point3f & Q_t) //{ // float R_len=Distance(R.P0(),R.P1()); // float Q_len=Distance(Q.P0(),Q.P1()); // const float EPSILON_LENGTH = std::max(R_len,Q_len)*0.0001f; // if(R_len < EPSILON_LENGTH){ // R_s=R.P0(); // Q_t=ClosestPoint(Q,R_s); // return std::make_pair(Distance(R_s,Q_t),true); // } // if( Q_len < EPSILON_LENGTH){ // Q_t=Q.P0(); // R_s=ClosestPoint(R,Q_t); // return std::make_pair(Distance(R_s,Q_t),true); // } // Point3f r0 = R.P0(), Vr = (R.P1()-R.P0()).normalized(); // Point3f q0 = Q.P0(), Vq = (Q.P1()-Q.P0()).normalized(); // float VRVR = Vr.dot(Vr); // float VQVQ = Vq.dot(Vq); // float VRVQ = Vr.dot(Vq); // const float det = ( VRVR * VQVQ ) - ( VRVQ * VRVQ ); // const float EPSILON = 0.00001f; // if ( ( det >= 0.0f ? det : -det) < EPSILON ) { // Line3f lR(R.P0(),R.P1()); // float qa=lR.Projection(Q.P0()); // float qb=lR.Projection(Q.P1()); // if( (qa<=0.0f) && qb<=(0.0f)){ // R_s=R.P0(); // Q_t=ClosestPoint(Q,R_s); // } else if ( (qa >= 1.0f) && (qb >= 1.0f) ){ // R_s=R.P1(); // Q_t=ClosestPoint(Q,R_s); // } else { // if( (qa >= 0.0f) && (qa <= 1.0f) ){ // Q_t=Q.P0(); // R_s=ClosestPoint(R,Q_t); // } else if((qb >= 0.0f) && (qb <= 1.0f) ){ // Q_t=Q.P1(); // R_s=ClosestPoint(R,Q_t); // } else { // if( ( ((qa<=0.0f)&&(qb>=1.0f)) || (((qb<=0.0f)&&(qa>=1.0f))))){ // R_s=R.P0(); // Q_t=ClosestPoint(Q,R_s); // }else{ // assert(0); // } // } // } // return std::make_pair(Distance(R_s,Q_t),true); // } // float b1= (q0 - r0).dot(Vr); // float b2= (r0 - q0).dot(Vq); // float s = ( (VQVQ * b1) + (VRVQ * b2) ) / det; // float t = ( (VRVQ * b1) + (VRVR * b2) ) / det; // if( s < 0 ){ // R_s = R.P0(); // }else if ( s > R_len ){ // R_s = R.P1(); // } else { // R_s = r0 + (Vr * s); // } // if( t < 0){ // Q_t = Q.P0(); // }else if ( t > Q_len ){ // Q_t = Q.P1(); // }else{ // Q_t = q0 + (Vq * t); // } // return std::make_pair(Distance(R_s,Q_t),false); //} /*! @brief Compute the point on a line closest to the ray projection of a window coordinate point. Given a window coordinate point, computes a ray starting from the manipulator camera eye and passing through the point's projection on the viewplane, then uses RayLineDistance() to get the closest point to ray on a given line. @see RayLineDistance(const Ray3f & R,const Line3f & Q,Point3f & R_s, Point3f & Q_t) @param tb the manipulator. @param axis the axis. @param point the window coordinate point. @return a std::pair made with the point on axis closest to the ray projection of point and a boolean true if and only if the ray doesn't diverges respect to the axis. */ std::pair< Point3f,bool > HitNearestPointOnAxis (Trackball * tb,Line3f axis, Point3f point) { Ray3fN ray = line2ray(tb->camera.ViewLineFromWindow (point)); Point3f axis_p(0,0,0), ray_p(0,0,0); std::pair< float, bool > resp=RayLineDistance(ray,axis,ray_p,axis_p); if(resp.second || (ray_p == ray.Origin())){ return std::make_pair(Point3f(0,0,0),false); } return std::make_pair(axis_p,true); } /*! @brief Project a line into a plane. Given a line and a plane, returns the line projection on the plane. The line returned is \e not normalized. @param ln the line. @param pl the plane. @return the (non normalized) line projected. */ Line3f ProjectLineOnPlane(const Line3f & ln, const Plane3f & pl) { Point3f l0=ln.Origin(); Point3f l1=l0+ln.Direction(); Point3f p1,p2; p1=pl.Projection(l0); p2=pl.Projection(l1); Line3f res(p1,p2-p1); return res; } /*! @brief Computes a signed line-point distance. Given a line, a point and a positivity direction, computes the signed distance between the line and the point. @param line the line. @param pt the point. @param positive_dir the positivity direction. @return the signed distance. */ float signedDistance(Line3f line,Point3f pt,Point3f positive_dir) { return Distance(line,pt) * ((((pt-ClosestPoint(line,pt)).dot(positive_dir)) >= 0.0f )? 1.0f: -1.0f); } /*! @brief Computes the verical component of an user mouse drag. @param tb the manipulator. @param new_point the new mouse pointer coordinate. @return The verical component of the user mouse drag. */ float getDeltaY(Trackball * tb, Point3f new_point) { float ScreenHeight = float (tb->camera.viewport[3] - tb->camera.viewport[1]); return (new_point[1] - tb->last_point[1]) / ScreenHeight; } /*! @brief Computes the intersection between a ray and a plane. @param pl the plane. @param ray the ray. @param po the intersection point. @return true if and only if there is intersection (po is valid). */ template inline bool IntersectionRayPlane( const Plane3 & pl, const Ray3 & ray, Point3 &po){ const T epsilon = T(1e-8); T k = pl.Direction().dot(ray.Direction()); // Compute 'k' factor if( (k > -epsilon) && (k < epsilon)) return false; T r = (pl.Offset() - pl.Direction().dot(ray.Origin()))/k; // Compute ray distance if (r < 0) return false; po = ray.Origin() + ray.Direction()*r; return true; } /*! @brief Project a window coordinate point on a plane. Given a window coordinate point, computes a ray starting from the manipulator camera eye and passing through the point's projection on the viewplane, then uses IntersectionRayPlane() to get the ray intersection with a given plane. @see IntersectionRayPlane() @param tb the manipulator. @param point the window coordinate point. @param plane the plane. @return a std::pair made with p's projection on the.plane and a boolean true if and only if the ray doesn't diverges respect to the plane. */ std::pair< Point3f, bool > HitPlane (Trackball * tb, Point3f point, Plane3f plane) { Ray3fN ray = line2ray(tb->camera.ViewLineFromWindow (point)); Point3f p(0,0,0); bool res = IntersectionRayPlane < float >(plane, ray, p); return std::make_pair(p,res); } // drawing section // nota: non ho scritto io questa classe, // quindi la documentazione doxy potrebbe non essere accurata al 100%. /*! @brief Drawing hints for manipulators This class is an holder for drawing-related variables. It's mainly used for SphereMode and InactiveMode drawings. */ class DrawingHint { public: /*! @brief Drawing hints constructor assign the drawing-related variables. */ DrawingHint () { CircleStep = 64; HideStill = false; DrawTrack = false; LineWidthStill = 0.9f; LineWidthMoving = 1.8f; color = Color4b::LightBlue; } /// The circles resolution. int CircleStep; /// currently not in use. bool HideStill; /// currently not in use. bool DrawTrack; /// circle color Color4b color; /// circle line width when inactive. float LineWidthStill; /// circle line width when active. float LineWidthMoving; }; /// the drawing hint used by the manipulators DrawingHint DH; // nota: non ho scritto io questa funzione, // quindi la documentazione doxy potrebbe non essere accurata al 100%. /*! @brief Draw 2 squares, used by DrawCircle(). */ void DrawPlaneHandle () { float r = 1.0; float dr = r / 10.0f; glBegin (GL_LINE_STRIP); glVertex3f (+r + dr, +r, 0.0); glVertex3f (+r, +r + dr, 0.0); glVertex3f (+r - dr, +r, 0.0); glVertex3f (+r, +r - dr, 0.0); glVertex3f (+r + dr, +r, 0.0); glEnd (); glBegin (GL_LINE_STRIP); glVertex3f (-r + dr, -r, 0.0); glVertex3f (-r, -r + dr, 0.0); glVertex3f (-r - dr, -r, 0.0); glVertex3f (-r, -r - dr, 0.0); glVertex3f (-r + dr, -r, 0.0); glEnd (); } // nota: non ho scritto io questa funzione, // quindi la documentazione doxy potrebbe non essere accurata al 100%. /*! @brief Draw a circle with 2 squares, used by DrawSphereIcon(). */ void DrawCircle (bool planehandle=true) { int nside = DH.CircleStep; const double pi2 = 3.14159265 * 2.0; glBegin (GL_LINE_LOOP); for (double i = 0; i < nside; i++) { glNormal3d (cos (i * pi2 / nside), sin (i * pi2 / nside), 0.0); glVertex3d (cos (i * pi2 / nside), sin (i * pi2 / nside), 0.0); } glEnd (); if(planehandle) DrawPlaneHandle(); } /*! @brief Draw a spherical manipulator icon. @param tb the manipulator. @param active boolean to be set to true if the icon is active. */ void DrawSphereIcon (Trackball * tb, bool active, bool planeshandle=false) { glPushAttrib(GL_TRANSFORM_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT); glMatrixMode(GL_MODELVIEW); glPushMatrix (); glDepthMask(GL_FALSE); Point3f center = tb->center + tb->track.InverseMatrix()*Point3f(0, 0, 0); glTranslate(center); glScale (tb->radius/tb->track.sca); float amb[4] = { .35f, .35f, .35f, 1.0f }; float col[4] = { .5f, .5f, .8f, 1.0f }; glEnable (GL_LINE_SMOOTH); if (active) glLineWidth (DH.LineWidthMoving); else glLineWidth (DH.LineWidthStill); glDisable(GL_COLOR_MATERIAL); // has to be disabled, it is used by wrapper to draw meshes, and prevent direct material setting, used here glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor (DH.color); glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, amb); col[0] = .40f; col[1] = .40f; col[2] = .85f; glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col); DrawCircle(planeshandle); glRotatef (90, 1, 0, 0); col[0] = .40f; col[1] = .85f; col[2] = .40f; glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col); DrawCircle(planeshandle); glRotatef (90, 0, 1, 0); col[0] = .85f; col[1] = .40f; col[2] = .40f; glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col); DrawCircle(planeshandle); glPopMatrix (); glPopAttrib (); } // TEMPORARY drawing section // Disclaimer: the following code is of VERY POOR quality // feel free to delete and rewrite everything /*! @brief Support function for the \e DrawUgly series of functions Prepare the OpenGL attributes. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... */ void prepare_attrib() { float amb[4] = { .3f, .3f, .3f, 1.0f }; float col[4] = { .5f, .5f, .8f, 1.0f }; glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glEnable (GL_LINE_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, amb); glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, col); } /*! @brief Support function for the \e DrawUgly series of functions. Draw a coordinate vector, usually a letter, near the manipulator icon in a user readable oriantation. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... @param tb the manipulator. @param ugly_letter the coordinate vector. */ void DrawUglyLetter(Trackball * tb,std::vector ugly_letter) { Point3f center=tb->camera.Project(tb->center); float offset=0; offset=(std::max)(offset,Distance(center,tb->camera.Project(tb->center+(Point3f(1,0,0) * tb->radius)))); offset=(std::max)(offset,Distance(center,tb->camera.Project(tb->center+(Point3f(0,1,0) * tb->radius)))); offset=(std::max)(offset,Distance(center,tb->camera.Project(tb->center+(Point3f(0,0,1) * tb->radius)))); glPushMatrix(); glPushAttrib (GL_ALL_ATTRIB_BITS); // go to world coords glTranslate (tb->center); glMultMatrix (tb->track.InverseMatrix ()); glTranslate (-tb->center); prepare_attrib(); glColor3f(1,1,1); glLineWidth(4.0); glBegin(GL_LINE_STRIP); for(unsigned int i=0;icamera.UnProject(center+(ugly_letter[i] * offset * 0.25) +Point3f(-offset,-offset,0))); } glEnd(); glPopAttrib (); glPopMatrix(); } /*! @brief PanMode drawing function, member of the \e DrawUgly series. Draw a PanMode manipulator in an ugly way. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... @param tb the manipulator. */ void DrawUglyPanMode(Trackball * tb) { std::vector ugly_p; ugly_p.push_back(Point3f(-1,-1,0)); ugly_p.push_back(Point3f(-1,1,0)); ugly_p.push_back(Point3f(1,1,0)); ugly_p.push_back(Point3f(1,0,0)); ugly_p.push_back(Point3f(-1,0,0)); DrawUglyLetter(tb,ugly_p); } /*! @brief ZMode drawing function, member of the \e DrawUgly series. Draw a ZMode manipulator in an ugly way. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... @param tb the manipulator. */ void DrawUglyZMode(Trackball * tb) { std::vector ugly_z; ugly_z.push_back(Point3f(-1,1,0)); ugly_z.push_back(Point3f(1,1,0)); ugly_z.push_back(Point3f(-1,-1,0)); ugly_z.push_back(Point3f(1,-1,0)); DrawUglyLetter(tb,ugly_z); } /*! @brief ScaleMode drawing function, member of the \e DrawUgly series. Draw a ScaleMode manipulator in an ugly way. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... @param tb the manipulator. */ void DrawUglyScaleMode(Trackball * tb) { std::vector ugly_s; ugly_s.push_back(Point3f(1,1,0)); ugly_s.push_back(Point3f(-1,1,0)); ugly_s.push_back(Point3f(-1,0,0)); ugly_s.push_back(Point3f(1,0,0)); ugly_s.push_back(Point3f(1,-1,0)); ugly_s.push_back(Point3f(-1,-1,0)); DrawUglyLetter(tb,ugly_s); } /*! @brief AxisMode drawing function, member of the \e DrawUgly series. Draw an AxisMode manipulator in an ugly way. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... @param tb the manipulator. @param axis AxisMode's axis. */ void DrawUglyAxisMode(Trackball * tb,Line3f axis) { glPushMatrix(); glPushAttrib (GL_ALL_ATTRIB_BITS); // go to world coords glTranslate (tb->center); glMultMatrix (tb->track.InverseMatrix ()); glTranslate (-tb->center); prepare_attrib(); glColor3f(0.9f, 0.9f, 0.2f); glLineWidth(2.0); glBegin(GL_LINES); glVertex(axis.Origin()+(axis.Direction()*100)); glVertex(axis.Origin()-(axis.Direction()*100)); glEnd(); glPointSize(8.0); glColor3f(0.2f, 0.2f, 0.9f); glBegin(GL_POINTS); glVertex(axis.Origin()); glEnd(); glPopAttrib (); glPopMatrix(); } /*! @brief PlaneMode drawing function, member of the \e DrawUgly series. Draw a PlaneMode manipulator in an ugly way. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... @param tb the manipulator. @param plane PlaneMode's plane. */ void DrawUglyPlaneMode(Trackball * tb,Plane3f plane) { glPushMatrix(); glPushAttrib (GL_ALL_ATTRIB_BITS); // go to world coords glTranslate (tb->center); glMultMatrix (tb->track.InverseMatrix ()); glTranslate (-tb->center); prepare_attrib(); Point3f p0,d1,d2,norm; norm=plane.Direction(); p0=plane.Projection(Point3f(0,0,0)); d1=Point3f(0,1,0); if(norm == d1 || norm == -d1) d1 = Point3f(1,0,0); d2=plane.Projection(d1); d1=(d2 - p0).normalized(); d2=(d1 ^ norm).normalized(); glLineWidth(3.0); glColor3f(0.2f, 0.2f, 0.9f); glBegin(GL_LINES); glVertex(p0); glVertex(p0+norm); glEnd(); glLineWidth(1.0); for(float i=0.5f; i<100.0f; i+=0.7f){ glBegin(GL_LINE_LOOP); for(int a=0;a<360;a+=10){ float f0=i*cosf((float(M_PI)*float(a))/180.0f); float f1=i*sinf((float(M_PI)*float(a))/180.0f); glVertex(p0+(d1*f0)+(d2*f1)); } glEnd(); } glColor3f(0.9f, 0.9f, 0.2f); glPointSize(8.0f); glBegin(GL_POINTS); glVertex(p0); glEnd(); glColor3f(0.7f, 0.7f, 0.0f); glPointSize(6.0); glBegin(GL_POINTS); glVertex(p0+norm); glEnd(); glPopAttrib (); glPopMatrix(); } /*! @brief CylinderMode drawing function, member of the \e DrawUgly series. Draw a CylinderMode manipulator in an ugly way. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... @param tb the manipulator. @param axis CylinderMode's axis. */ void DrawUglyCylinderMode(Trackball * tb,Line3f axis) { glPushMatrix(); glPushAttrib (GL_ALL_ATTRIB_BITS); // go to world coords glTranslate (tb->center); glMultMatrix (tb->track.InverseMatrix ()); glTranslate (-tb->center); prepare_attrib(); Plane3f plane; plane.Init(axis.Origin(),axis.Direction()); Point3f p0,d1,d2,norm; norm=plane.Direction(); p0=plane.Projection(Point3f(0,0,0)); d1=Point3f(0,1,0); if(norm == d1 || norm == -d1) d1 = Point3f(1,0,0); d2=plane.Projection(d1); d1=(d2 - p0).normalized(); d2=(d1 ^ norm).normalized(); glLineWidth(1.0); glColor3f(0.2f, 0.2f, 0.9f); for(int i=-100;i<100;i++){ glBegin(GL_LINE_LOOP); for(int a=0;a<360;a+=10){ float f0=(tb->radius)*cosf((float(M_PI)*float(a))/180.0f); float f1=(tb->radius)*sinf((float(M_PI)*float(a))/180.0f); glVertex(axis.Origin()+p0+(norm*float(i))+(d1*f0)+(d2*f1)); } glEnd(); } glLineWidth(3.0); glColor3f(0.2f, 0.2f, 0.9f); glBegin(GL_LINES); glVertex(axis.Origin()); glVertex(axis.Origin()+(axis.Direction()*100)); glEnd(); glLineWidth(1.5); glColor3f(0.9f, 0.2f, 0.9f); glBegin(GL_LINES); glVertex(axis.Origin()); glVertex(axis.Origin()-(axis.Direction()*100)); glEnd(); glColor3f(0.9f, 0.9f, 0.2f); glPointSize(8.0); glBegin(GL_POINTS); glVertex(axis.Origin()); glEnd(); glPopAttrib (); glPopMatrix(); } /*! @brief PathMode drawing function, member of the \e DrawUgly series. Draw a PathMode manipulator in an ugly way. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... @param tb the manipulator. @param points PathMode's points. @param current_point PathMode's current point. @param prev_point PathMode's prev point. @param next_point PathMode's next point. @param old_hitpoint PathMode's old hitpoint. @param wrap PathMode's wrap. */ void DrawUglyPathMode(Trackball * tb,const std::vector < Point3f > &points, Point3f current_point,Point3f prev_point, Point3f next_point,Point3f old_hitpoint,bool wrap) { glPushMatrix(); glPushAttrib (GL_ALL_ATTRIB_BITS); // go to world coords glTranslate (tb->center); glMultMatrix (tb->track.InverseMatrix ()); glTranslate (-tb->center); prepare_attrib(); glColor3f(0.9f, 0.9f, 0.2f); glLineWidth(2.0); if(wrap) glBegin(GL_LINE_LOOP); else glBegin(GL_LINE_STRIP); for (std::vector < Point3f >::const_iterator i = points.begin (); i != points.end (); ++i){ glVertex(*i); } glEnd(); glColor3f(1,0,1); glPointSize(8.0); glBegin(GL_POINTS); glVertex(current_point); glEnd(); glColor3f(0.6f, 0.0f, 0.6f); glPointSize(7.0); glBegin(GL_POINTS); glVertex(old_hitpoint); glEnd(); glColor3f(0.7f, 0.7f, 0.7f); glPointSize(6.5); glBegin(GL_POINTS); glVertex(prev_point); glVertex(next_point); glEnd(); glPopAttrib (); glPopMatrix(); } /*! @brief AreaMode drawing function, member of the \e DrawUgly series. Draw an AreaMode manipulator in an ugly way. \warning this method is part of the \e DrawUgly series of functions, which is a \b TEMPORARY solution, used while waiting for the \e DrawBeautiful series... @param tb the manipulator. @param points AreaMode's points. @param status AreaMode's status. @param old_status AreaMode's old status. @param plane AreaMode's plane. @param path AreaMode's path. @param rubberband_handle AreaMode's rubberband handle. */ void DrawUglyAreaMode(Trackball * tb,const std::vector < Point3f > &points, Point3f status,Point3f old_status,Plane3f plane, const std::vector < Point3f > &path,Point3f rubberband_handle) { glPushMatrix(); glPushAttrib (GL_ALL_ATTRIB_BITS); // go to world coords glTranslate (tb->center); glMultMatrix (tb->track.InverseMatrix ()); glTranslate (-tb->center); prepare_attrib(); glColor3f(0.9f, 0.9f, 0.2f); glLineWidth(2.0); glBegin(GL_LINE_LOOP); for (std::vector < Point3f >::const_iterator i = points.begin (); i != points.end (); ++i){ glVertex(*i); } glEnd(); glColor3f(0.0f, 0.9f, 0.2f); glLineWidth(1.2f); glBegin(GL_LINE_STRIP); for (std::vector < Point3f >::const_iterator i = path.begin (); i != path.end (); ++i){ glVertex(*i); } glEnd(); glColor3f(1,0,1); glPointSize(8.0); glBegin(GL_POINTS); glVertex(status); glEnd(); glColor3f(0.6f, 0.0f, 0.6f); glPointSize(7.0); glBegin(GL_POINTS); glVertex(old_status); glEnd(); glColor3f(0.6f, 0.0f, 0.0f); glPointSize(6.0); glBegin(GL_POINTS); glVertex(rubberband_handle); glEnd(); glLineWidth(1.0); glBegin(GL_LINES); glVertex(rubberband_handle); glVertex(status); glEnd(); Point3f p0,d1,d2,norm; norm=plane.Direction(); p0=plane.Projection(Point3f(0,0,0)); d1=Point3f(0,1,0); if(norm == d1 || norm == -d1) d1 = Point3f(1,0,0); d2=plane.Projection(d1); d1=(d2 - p0).normalized(); d2=(d1 ^ norm).normalized(); glLineWidth(3.0); glColor3f(0.2f, 0.2f, 0.9f); glBegin(GL_LINES); glVertex(p0); glVertex(p0+norm); glEnd(); glLineWidth(0.1f); for(float i=0.5f;i<100.0f; i+=0.7f){ glBegin(GL_LINE_LOOP); for(int a=0;a<360;a+=10){ float f0=i*cosf((float(M_PI)*float(a))/180.0f); float f1=i*sinf((float(M_PI)*float(a))/180.0f); glVertex(p0+(d1*f0)+(d2*f1)); } glEnd(); } glPopAttrib (); glPopMatrix(); } } //end namespace trackutils } //end namespace vcg #endif //TRACKUTILS_H meshlab-1.3.2+dfsg1/vcglib/wrap/gui/activecoordinateframe.h0000644000175000017500000001457211517500603022577 0ustar gladkgladk/**************************************************************************** * 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.1 2008/03/02 16:44:18 benedetti moved ActiveCoordinateFrame to its own files ****************************************************************************/ #ifndef ACTIVECOORDINATEFRAME_H #define ACTIVECOORDINATEFRAME_H #include "coordinateframe.h" #include #include namespace vcg { /*! @brief The ActiveCoordinateFrame class. This class implements an eulerian trackball over a Movable Coordinate Frame. */ class ActiveCoordinateFrame: public MovableCoordinateFrame { public: /*! @brief The constructor. Initialize the ActiveCoordinateFrame data. @param size the distance from the origin to the endpoint of the arrows. */ ActiveCoordinateFrame(float size); /*! @brief The destructor. The destructor. */ virtual ~ActiveCoordinateFrame(); /*! @brief Render the active coordinate frame in its position. @param glw the GL widget. */ virtual void Render(QGLWidget* glw); /*! @brief Reset the position and/or the rotation of the coordinate frame. @param reset_position set to true to reset the position. @param reset_alignment set to true to reset the rotation. */ virtual void Reset(bool reset_position,bool reset_alignment); /*! @brief Set the position of the coordinate frame. @param new_position the new position of the coordinate frame. */ virtual void SetPosition(const Point3f new_position); /*! @brief Set the rotation of the coordinate frame. @param new_rotation the new rotation of the coordinate frame. */ virtual void SetRotation(const Quaternionf rotation); /*! @brief Align the coordinate frame to one or two directions. If the primary direction of alignment is null this function does nothing, otherwise two rotations are performed: the first rotation aligns the axis named axis_1 to the primary direction of alignment, the second rotation never moves axis_1 away from the primary direction. If the secondary direction of alignment is not null and is not parallel to the primary direction the axis named axis_2 is rotated as much as possible to be aligned to secondary direction. If the secondary direction of alignment is null the axis named axis_2 is rotated as much as possible to be realigned to its old direction, if this is impossible the remaining axis is used. @param primary the primary direction of alignment. @param secondary the secondary direction of alignment. @param axis_1 the name of the axis to align to the primary direction, must be a char choosen from 'X', 'Y' and 'Z' @param axis_2 the name of the axis to align to the secondary direction, must be different from axis_1 and must be a char choosen from 'X', 'Y', 'Z' and ' '; if the char is ' ' the axis is choosen automatically. */ virtual void AlignWith(const Point3f primary, const Point3f secondary, const char axis_1, const char axis_2); /*! @brief Interface function relative to mouse down event in QT. @param x the x coordinate of the cursor. @param y the y coordinate of the cursor. @param button the keyboard modifiers state. */ void MouseDown(int x, int y, int button); /*! @brief Interface function relative to mouse move event in QT. @param x the x coordinate of the cursor. @param y the y coordinate of the cursor. */ void MouseMove(int x, int y); /*! @brief Interface function relative to mouse up event in QT. @param x the x coordinate of the cursor. @param y the y coordinate of the cursor. @param button the keyboard modifiers state. */ void MouseUp(int x, int y, int button); /*! @brief Interface function relative to keyboard up event in QT. @param button the keyboard modifiers state. */ void ButtonUp(int button); /*! @brief Interface function relative to keyboard down event in QT. @param button the keyboard modifiers state. */ void ButtonDown(int button); /*! @brief Set rotational snap value. @param value the new rotational snap value, in degrees. */ void SetSnap(float value); /// The eulerian trackball. Trackball *manipulator; /// The flag that enables moves feedback rendering bool drawmoves; /// The flag that enables rotations feedback rendering bool drawrotations; protected: // data: const int move_button,rotate_button; const int x_modifier,y_modifier,z_modifier; Point3f x_axis,y_axis,z_axis; float rot_snap_rad,mov_snap; // functions: virtual void Move(const Similarityf); void Update(); private: int movx,movy,movz,rotx,roty,rotz; }; }//namespace #endif /*ACTIVECOORDINATEFRAME_H*/ meshlab-1.3.2+dfsg1/vcglib/wrap/gui/coordinateframe.cpp0000644000175000017500000002777411517500603021746 0ustar gladkgladk/**************************************************************************** * 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); } meshlab-1.3.2+dfsg1/vcglib/wrap/gui/activecoordinateframe.cpp0000644000175000017500000002214211517500603023122 0ustar gladkgladk/**************************************************************************** * 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.1 2008/03/02 16:44:18 benedetti moved ActiveCoordinateFrame to its own files ****************************************************************************/ #include #include #include #include #include "activecoordinateframe.h" using namespace vcg; ActiveCoordinateFrame::ActiveCoordinateFrame(float size) :MovableCoordinateFrame(size),manipulator(NULL),drawmoves(true), drawrotations(true),move_button(Trackball::BUTTON_RIGHT), rotate_button(Trackball::BUTTON_LEFT),x_modifier(Trackball::BUTTON_NONE), y_modifier(Trackball::KEY_CTRL),z_modifier(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), movx(move_button | x_modifier),movy(move_button | y_modifier), movz(move_button | z_modifier),rotx(rotate_button | x_modifier), roty(rotate_button | y_modifier),rotz(rotate_button | z_modifier) { manipulator=new Trackball(); Update(); } ActiveCoordinateFrame::~ActiveCoordinateFrame() { if(manipulator!=NULL) { delete manipulator; manipulator=NULL; } } void ActiveCoordinateFrame::Render(QGLWidget* glw) { glPushMatrix(); manipulator->radius=size; manipulator->center=position; manipulator->GetView(); manipulator->Apply(false); MovableCoordinateFrame::Render(glw); // got nothing to draw if(!drawmoves && !drawrotations){ glPopMatrix(); 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); // maybe got something to draw 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); QString message("this should never be seen"); char axis_name; float verse; if(current_mode==x_modifier){ glColor(xcolor); message = QString("move or rotate on X axis"); } else if(current_mode==y_modifier){ glColor(ycolor); message = QString("move or rotate on Y axis"); } else if(current_mode==z_modifier){ glColor(zcolor); message = QString("move or rotate on Z axis"); } else if(rotating && drawrotations){ // draw a rotation Point3f axis, arc_point; float angle; manipulator->track.rot.ToAxis(angle,axis); angle = -angle; if(current_mode==rotx){ verse=((axis+x_axis).Norm()<1?-1:1); glColor(xcolor); axis_name='x'; arc_point=y_axis*(size*0.8); } else if(current_mode==roty) { verse=((axis+y_axis).Norm()<1?-1:1); glColor(ycolor); axis_name='y'; arc_point=z_axis*(size*0.8); } else if(current_mode==rotz) { verse=((axis+z_axis).Norm()<1?-1:1); glColor(zcolor); axis_name='z'; arc_point=x_axis*(size*0.8); } else assert(0); // normalizing rotation between -180 and 180 degrees 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); 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){ // draw a traslation Point3f ntra=manipulator->track.tra; ntra.Normalize(); if(current_mode==movx){ verse=((ntra+x_axis).Norm()<1?-1:1); glColor(xcolor); axis_name='x'; }else if(current_mode==movy){ verse=((ntra+y_axis).Norm()<1?-1:1); glColor(ycolor); axis_name='y'; }else if(current_mode==movz){ verse=((ntra+z_axis).Norm()<1?-1:1); glColor(zcolor); axis_name='z'; }else assert(0); 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); glBegin(GL_LINES); glVertex(position); glVertex(old_pos); glEnd(); glBegin(GL_POINTS); glVertex(old_pos); glEnd(); } else { // got nothing to draw glPopAttrib(); glPopMatrix(); return; } // draw message below cursor font.setBold(true); font.setPixelSize(12); QPoint cursor=glw->mapFromGlobal(glw->cursor().pos()); glw->renderText(cursor.x()+16,cursor.y()+16,message,font); glPopAttrib(); glPopMatrix(); } 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,const char c1,const char c2) { MovableCoordinateFrame::AlignWith(primary,secondary,c1,c2); Update(); manipulator->Reset(); } void ActiveCoordinateFrame::MouseDown(int x, int y, /*Button*/ int button) { Move(manipulator->track); manipulator->Reset(); manipulator->MouseDown(x,y,button); } void ActiveCoordinateFrame::MouseMove(int x, int y) { 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() { movx=(move_button | x_modifier); movy=(move_button | y_modifier); movz=(move_button | z_modifier); rotx=(rotate_button | x_modifier); roty=(rotate_button | y_modifier); rotz=(rotate_button | z_modifier); 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)); manipulator->ClearModes(); manipulator->modes[0] = NULL; manipulator->modes[movx] = new AxisMode(p,x_axis); manipulator->modes[movy] = new AxisMode(p,y_axis); manipulator->modes[movz] = new AxisMode(p,z_axis); manipulator->modes[rotx] = new CylinderMode(p,x_axis,rot_snap_rad); manipulator->modes[roty] = new CylinderMode(p,y_axis,rot_snap_rad); manipulator->modes[rotz] = new CylinderMode(p,z_axis,rot_snap_rad); manipulator->SetCurrentAction(); } meshlab-1.3.2+dfsg1/vcglib/wrap/gui/trackrecorder.h0000644000175000017500000000602011517500603021060 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.1 2005/04/14 21:23:39 ganovelli *** empty log message *** ****************************************************************************/ #ifndef VCGLIB_TRACKRECORDER #define VCGLIB_TRACKRECORDER #include #include #include namespace vcg{ struct TrackRecorder{ TrackRecorder(){Stop();} FILE * trackfile; enum { PLAY,REC,OFF } mode; int nextTime, startTime; void StartPlaying(char * namefile){ if(trackfile != NULL) return; trackfile = fopen(namefile,"rb"); startTime = clock(); mode = PLAY; fread(&nextTime,4,1,trackfile); } void UpdateTrackball(Trackball & t){ while( ( clock()-startTime > nextTime)&& !feof(trackfile)){ fread(&t.track,sizeof(float)*4 + sizeof(float)*5,1,trackfile); fread(&nextTime,4,1,trackfile); } if(feof(trackfile)) Stop(); } void StartRecording(char * namefile){ if(trackfile != NULL) return; trackfile = fopen(namefile,"wb"); startTime = clock(); mode = REC; } void RecordTrackball(Trackball & t){ nextTime = clock()-startTime; fwrite(&nextTime,4,1,trackfile); fwrite(&t.track,sizeof(float)*4 + sizeof(float)*5,1,trackfile); } void Stop(){mode = OFF; trackfile = NULL;}; }; } #endifmeshlab-1.3.2+dfsg1/vcglib/wrap/gui/trackball.cpp0000644000175000017500000003025711732414757020546 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ #include #include "trackball.h" #include #include #include using namespace vcg; Transform::Transform() { track.SetIdentity(); radius=1.0f; center=Point3f(0,0,0); } Trackball::Trackball(): current_button(0), current_mode(NULL), inactive_mode(NULL), dragging(false), last_time(0), spinnable(true), spinning(false), history_size(10), fixedTimestepMode(false) { setDefaultMapping (); } Trackball::~Trackball() { ClearModes(); delete inactive_mode; } void Trackball::ClearModes() { // Note: people ofter maps different keys to the same modes. // so we should avoid double deletion of these double referenced modes. std::set goodModes; std::map::iterator it; for(it = modes.begin(); it != modes.end(); it++) if ((*it).second) goodModes.insert( (*it).second); std::set::iterator its; for(its = goodModes.begin(); its != goodModes.end(); its++) delete *its; modes.clear(); } void Trackball::setDefaultMapping () { idle_and_keys_mode = NULL; inactive_mode = new InactiveMode (); ClearModes(); modes[0] = NULL; modes[BUTTON_MIDDLE | KEY_ALT] = modes[BUTTON_LEFT] = new SphereMode (); modes[BUTTON_LEFT | KEY_CTRL] = new PanMode (); modes[BUTTON_MIDDLE] = new PanMode (); modes[WHEEL] = modes[BUTTON_LEFT | KEY_SHIFT] = new ScaleMode (); modes[BUTTON_LEFT | KEY_ALT] = new ZMode (); } void Trackball::SetIdentity() { track.SetIdentity(); Reset(); } void Trackball::SetPosition(const Point3f &c, int /* millisec */) { center = c; } void Trackball::GetView() { camera.GetView(); } // the drawing code has been moved to the trackmodes void Trackball::DrawPostApply() { if(current_mode !=NULL){ current_mode->Draw(this); }else{ if (inactive_mode != NULL) inactive_mode->Draw(this); } } void Trackball::Apply () { glTranslate (center); glMultMatrix (track.Matrix()); glTranslate (-center); } void Trackball::Apply(bool ToDraw) { Apply(); if(ToDraw){ DrawPostApply(); } } void Trackball::ApplyInverse() { glTranslate(center); glMultMatrix(track.InverseMatrix()); glTranslate(-center); } // T(c) S R T(t) T(-c) => S R T(S^(-1) R^(-1)(c) + t - c) Matrix44f Trackball::Matrix() const{ #ifndef VCG_USE_EIGEN Matrix44f r; track.rot.ToMatrix(r); Matrix44f sr = Matrix44f().SetScale(track.sca, track.sca, track.sca) * r; Matrix44f s_inv = Matrix44f().SetScale(1/track.sca, 1/track.sca, 1/track.sca); Matrix44f t = Matrix44f().SetTranslate(s_inv*r.transpose()*center + track.tra - center); return Matrix44f(sr*t); #else Eigen::Quaternionf rot(track.rot); Eigen::Translation3f tr( (1/track.sca) * (rot.inverse() * center) + track.tra - center ); return ( Eigen::Scaling3f(track.sca) * (rot * tr) ).matrix(); #endif } Matrix44f Trackball::InverseMatrix() const{ return Inverse(Matrix()); } void Trackball::Scale(const float s) { track.sca*=s; } void Trackball::Translate(Point3f tr) { Quaternionf irot = track.rot; irot.Invert(); track.tra = last_track.tra + irot.Rotate(tr)/track.sca; } /***************************************************************/ // DrawCircle () e DrawPlane() have been moved to trackutils.h // the drawing code has been moved to the trackmodes /* void Trackball::DrawCircle() { int nside=DH.CircleStep; const double pi2=3.14159265*2.0; glBegin(GL_LINE_LOOP); for(double i=0;i::iterator i; for(i = modes.begin(); i != modes.end(); i++){ TrackMode * mode=(*i).second; if(mode!=NULL) mode->Reset(); } if (inactive_mode != NULL) inactive_mode->Reset(); } //interface void Trackball::MouseDown(int button) { undo_track = track; current_button |= button; SetCurrentAction(); Hits.clear(); } void Trackball::MouseDown(int x, int y, int button) { undo_track = track; current_button |= button; SetCurrentAction(); last_point = Point3f((float)x, (float)y, 0); Hits.clear(); } void Trackball::MouseMove(int x, int y) { if(current_mode == NULL) return; if(last_point[2] == -1) { //changed mode in the middle of moving last_point = Point3f((float)x, (float)y, 0); return; } undo_track = track; current_mode->Apply(this, Point3f(float(x), float(y), 0)); } bool Trackball::IsAnimating(unsigned int msec){ bool res; if(idle_and_keys_mode == NULL) res=false; else res=idle_and_keys_mode->IsAnimating(this); if (!fixedTimestepMode) { if (msec==0) msec = clock()*1000/CLOCKS_PER_SEC; if (!res) { last_time = msec; } } return res; } void Trackball::Sync(unsigned int msec) { if (!fixedTimestepMode) Animate(msec); } void Trackball::Animate(unsigned int msec){ unsigned int delta; if (fixedTimestepMode) delta=msec; else { if (msec==0) msec = clock()*1000/CLOCKS_PER_SEC; delta = msec -last_time; last_time = msec; } if(idle_and_keys_mode == NULL) return; idle_and_keys_mode->Animate(delta,this); } void Trackball::MouseUp(int /* x */, int /* y */, int button) { undo_track = track; ButtonUp(vcg::Trackball::Button(button)); //current_button &= (~button); //SetCurrentAction(); } // it assumes that a notch of 1.0 is a single step of the wheel void Trackball::MouseWheel(float notch) { undo_track = track; int buttons = current_button; current_button = WHEEL | (buttons&(KEY_SHIFT|KEY_CTRL|KEY_ALT)); SetCurrentAction(); if (current_mode == NULL) { //ScaleMode scalemode; //scalemode.Apply (this, notch); } else { current_mode->Apply(this, notch); } current_button = buttons; SetCurrentAction(); } void Trackball::MouseWheel(float notch, int button) { undo_track = track; current_button |= button; SetCurrentAction(); if (current_mode == NULL) { ScaleMode scalemode; scalemode.Apply (this, notch); } else { current_mode->Apply (this, notch); } current_button &= (~button); SetCurrentAction (); } void Trackball::ButtonDown(Trackball::Button button, unsigned int msec) { Sync(msec); bool old_sticky=false, new_sticky=false; assert (modes.count (0)); Button b=Button(current_button & MODIFIER_MASK); if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) old_sticky = modes[b]->isSticky(); current_button |= button; b=Button(current_button & MODIFIER_MASK); if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) new_sticky = modes[b]->isSticky(); if ( !old_sticky && !new_sticky) SetCurrentAction(); } void Trackball::ButtonUp(Trackball::Button button) { bool old_sticky=false, new_sticky=false; assert (modes.count (0)); Button b=Button(current_button & MODIFIER_MASK); if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) old_sticky = modes[b]->isSticky(); current_button &= (~button); b=Button(current_button & MODIFIER_MASK); if ( ( modes.count (b) ) && ( modes[b] != NULL ) ) new_sticky = modes[b]->isSticky(); if ( !old_sticky && !new_sticky) SetCurrentAction(); } void Trackball::Undo(){ track = undo_track; if(current_mode != NULL) current_mode->Undo(); } //spinning interface void Trackball::SetSpinnable(bool /* on*/ ){} bool Trackball::IsSpinnable() { return spinnable; } void Trackball::SetSpinning(Quaternionf &/* spin*/){} void Trackball::StopSpinning(){} bool Trackball::IsSpinning() { return spinning; } //navigation interface: void Trackball::Back(){} void Trackball::Forward(){} void Trackball::Home(){} void Trackball::HistorySize(int /* length */){} void Trackball::SetCurrentAction () { //I use strict matching. assert (modes.count (0)); if (!modes.count (current_button & MODIFIER_MASK)) { current_mode = NULL; } else { current_mode = modes[current_button & MODIFIER_MASK]; if(current_mode != NULL) current_mode->SetAction(); } last_point = Point3f (0, 0, -1); last_track = track; } ////return center of trackball in Window coordinates. //Point3f Trackball::ScreenOrigin() { // return camera.Project(ModelOrigin()); //} //return center of trackball in Model coordinates //Point3f Trackball::ModelOrigin() { // return center; //} //Matrix44f Trackball::ScreenToModel() { // return camera.inverse; //} // //Similarityf Trackball::ModelToLocal() { // Similarityf m = local * last_track; // return m; //} meshlab-1.3.2+dfsg1/vcglib/wrap/gui/trackmode.h0000644000175000017500000007634511517500603020220 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.15 2007/07/14 12:43:44 benedetti Added Doxygen documentation. Revision 1.14 2007/07/09 22:47:18 benedetti Removed using namespace std and modified accordingly. Revision 1.13 2007/06/25 10:21:38 fiorin Added some std:: here and there Revision 1.12 2007/06/13 17:15:09 benedetti Added one-level undo system and sticky trackmodes. Revision 1.11 2007/05/15 14:59:10 benedetti Main restructuring. added many new modes Revision 1.10 2007/02/26 01:30:02 cignoni Added reflection Name Revision 1.9 2006/02/13 13:10:27 cignoni Added Zmode for moving objects along the perpendicular to the viewplane Revision 1.8 2004/07/18 06:54:08 cignoni Added Scaling Revision 1.7 2004/07/11 22:06:56 cignoni Added scaling by wheel Revision 1.6 2004/06/09 14:01:13 cignoni Heavily restructured. To be completed only rotation works... Revision 1.5 2004/05/14 03:15:09 ponchio Redesigned partial version. Revision 1.4 2004/05/07 12:46:08 cignoni Restructured and adapted in a better way to opengl Revision 1.3 2004/04/07 10:54:11 cignoni Commented out unused parameter names and other minor warning related issues Revision 1.2 2004/03/25 14:55:25 ponchio Adding copyright. ****************************************************************************/ #ifndef TRACKMODE_H #define TRACKMODE_H #include #include #include #include #include namespace vcg { class Trackball; /*! @brief Base class for all the manipulators. Functions in this class implements the default behaviour of a manipulator: doing nothing. Every manipulator must be subclass of this class. */ class TrackMode { public: /*! @brief The default virtual destructor */ virtual ~TrackMode () { } /*! @brief The default manipulator application for mouse drags. This default application does nothing. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ virtual void Apply (Trackball * trackball, Point3f new_point); /*! @brief The default manipulator application for mouse scrolls. This default application does nothing. @param trackball the manipulator manager. @param WheelNotch the mouse wheel notch. */ virtual void Apply (Trackball * trackball, float WheelNotch); /*! @brief The default manipulator's begin action function. This default implementation does nothing. */ virtual void SetAction (); /*! @brief The default manipulator's reset function. If a manipulator has a state, it can be reset to the inital state calling this function. */ virtual void Reset (); /*! @brief The default manipulator's name. @return the constant string "TrackMode" */ virtual const char *Name (){ return "TrackMode"; }; /*! @brief The default manipulator's render function. @param trackball the manipulator manager. */ virtual void Draw (Trackball * trackball); /*! @brief The default avaibility to manipulator changes inside an action. Every manipulator class can choose if the manipulator manager can switch between it and another manipulator in the middle of an user action, e.g. switching Trackball's current_mode without releasing the mouse button. The default behaviour is to allow the switch. Blocking switches is useful for stateful manipulators, regarding state consistency respect to Trackball's %Undo() calls. @return false if manipulator permits the switch. */ virtual bool isSticky(); /*! @brief The default manipulator's undo function. If a manipulator has a state, it must be undoable with a call of this function. The undo must recreate the state present before the last Apply() call. This default implementation does nothing. */ virtual void Undo(); virtual bool IsAnimating(const Trackball *tb); virtual void Animate(unsigned int msec, Trackball *tb); }; /*! @brief An inactive manipulator. This manipulator is useful only for drawing the inactive trackball and for feeding occasional Trackball's modes with inactive manipulators. */ class InactiveMode:public TrackMode { public: /*! @brief Return this manipulator's name. @return the constant string "InactiveMode" */ const char *Name () { return "InactiveMode"; }; /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); }; /* View space modes */ // old interfaces /* class SphereMode: public TrackMode { } class CylinderMode: public TrackMode { } class PlaneMode: public TrackMode { } class ZMode: public TrackMode { } class LineMode: public TrackMode { } class LineMode: public TrackMode { } class ScaleMode: public TrackMode { */ // Sphere mode. /*! @brief The classic \e arcball manipulator. This class implements the classic free rotation manipulator, called \e arcball or \e trackball. This is a stateless manipulator, result of the Apply function is determined only by the mouse coordinates. */ class SphereMode:public TrackMode { public: /*! @brief Apply a rotation, function of the user mouse drag action. Map a mouse drag action on a rotation, and apply the rotation to the manipulated objects. If the user does not hit the sphere that surrounds the manipulated object(s), a rotational hyperboloid is used to compute the rotation. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ void Apply (Trackball * trackball, Point3f new_point); /*! @brief Return this manipulator's name. @return the constant string "SphereMode" */ const char *Name () { return "SphereMode"; }; /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); }; // Panning mode. /*! @brief The panning manipulator. This manipulator implements a bidimensional translation on the view plane. This is a stateless manipulator, result of the Apply function is determined only by the mouse coordinates. */ class PanMode:public TrackMode { public: /*! @brief Apply a translation, function of the user mouse drag action. The manipulated object is dragged in the plane parallel to the screen. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ void Apply (Trackball * trackball, Point3f new_point); /*! @brief Return this manipulator's name. @return the constant string "PanMode" */ const char *Name () { return "PanMode"; }; /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); }; // Z mode. /*! @brief The Z-directional manipulator. This manipulator implements a monodimensional translation on the axis normal to the view plane. Dragging the mouse up and down or scrolling the mouse wheel will move the object along the Z of the camera. This is a stateless manipulator, result of the Apply functions is determined only either by the mouse coordinates or by the mouse wheel notch. */ class ZMode:public TrackMode { public: /*! @brief Return this manipulator's name. @return the constant string "ZMode" */ const char *Name () { return "ZMode"; }; /*! @brief Apply a translation, function of the user mouse drag action. The manipulated object is moved along the Z of the camera: - Dragging the mouse down will move the object nearer to the camera. - Dragging the mouse up will move the object farther from the camera. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ void Apply (Trackball * trackball, Point3f new_point); /*! @brief Apply a translation, function of the user mouse wheel action. The manipulated object is moved along the Z of the camera: - Scrolling the mouse wheel down will move the object nearer to the camera. - Scrolling the mouse wheel up will move the object farther from the camera. @param trackball the manipulator manager. @param WheelNotch the mouse wheel notch. */ void Apply (Trackball * trackball, float WheelNotch); /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); }; // Scale Mode. /*! @brief The scale manipulator. This manipulator implements a scaling transformation. Dragging the mouse up and down or scrolling the mouse wheel will scale the object. This is a stateless manipulator, result of the Apply functions is determined only either by the mouse coordinates or by the mouse wheel notch. */ class ScaleMode:public TrackMode { public: /*! @brief Return this manipulator's name. @return the constant string "ScaleMode" */ const char *Name () { return "ScaleMode"; }; /*! @brief Apply a scaling, function of the user mouse drag action. The manipulated object is scaled in this way: - Dragging the mouse up will scale the object to a smaller dimension. - Dragging the mouse down will scale the object to a greater dimension. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ void Apply (Trackball * trackball, Point3f new_point); /*! @brief Apply a scaling, function of the user mouse wheel action. The manipulated object is scaled in this way: - Scrolling the mouse wheel up will scale the object to a smaller dimension. - Scrolling the mouse wheel down will scale the object to a greater dimension. @param trackball the manipulator manager. @param WheelNotch the mouse wheel notch. */ void Apply (Trackball * trackball, float WheelNotch); /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); }; // Axis mode. /*! @brief The one-directional manipulator. This manipulator implements a monodimensional translation on a constrained direction. Dragging the mouse up and down or scrolling the mouse wheel will move the object along the direction. This is a stateless manipulator, result of the Apply functions is determined only either by the mouse coordinates or by the mouse wheel notch. */ class AxisMode:public TrackMode { public: /*! @brief The line constructor. This manipulator needs to be initialized with a direction. This constructor can initialize it with a Line3f. The line will be normalized. @param ln the line that represent the direction. */ AxisMode (const Line3f & ln) : axis (ln) { } /*! @brief The origin-direction constructor. This manipulator needs to be initialized with a direction. This constructor can initialize it with two Point3f, representing a point and a vector. @param origin a point on the line. @param direction the line direction. */ AxisMode (const Point3f & origin, const Point3f & direction) : axis(Line3fN (origin, direction)) { } /*! @brief Return this manipulator's name. @return the constant string "AxisMode" */ const char *Name () { return "AxisMode"; }; /*! @brief Apply a translation, function of the user mouse drag action. The manipulated object is moved along the direction. If the pointer ray is divergent from the direction the object is not moved. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ void Apply (Trackball * trackball, Point3f new_point); /*! @brief Apply a translation, function of the user mouse wheel action. The manipulated object is moved along the direction. @param trackball the manipulator manager. @param WheelNotch the mouse wheel notch. */ void Apply (Trackball * trackball, float WheelNotch); /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); private: /// The direction, stored as a normalized line. Line3fN axis; }; // Plane mode. /*! @brief The planar manipulator. This manipulator implements a bidimensional translation on a constrained plane. This is a stateless manipulator, result of the Apply function is determined only by the mouse coordinates. */ class PlaneMode:public TrackMode { public: /*! @brief The plane costants constructor. This manipulator needs to be initialized with a plane. This constructor can initialize it with the four coefficients of the plane equation \f$ ax + by + cz + d = 0 \f$. @param a the first coefficient of the plane equation. @param b the second coefficient of the plane equation. @param c the third coefficient of the plane equation. @param d the fourth coefficient of the plane equation. */ PlaneMode (float a, float b, float c, float d) : plane(Plane3f(d,Point3f(a,b,c))){ } /*! @brief The plane constructor. This manipulator needs to be initialized with a plane. This constructor can initialize it with a Plane3f. @param pl the plane. */ PlaneMode (Plane3f & pl) : plane(pl) { } /*! @brief Return this manipulator's name. @return the constant string "PlaneMode" */ const char *Name () { return "PlaneMode"; }; /*! @brief Apply a translation, function of the user mouse drag action. The manipulated object is dragged in the plane. If the pointer ray is divergent from the plane the object is not moved. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ void Apply (Trackball * trackball, Point3f new_point); /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); private: /// The plane. Plane3f plane; }; // Cylinder mode. /*! @brief The constrained rotation manipulator. This manipulator implements a rotation manipulator, that make the rotation constrained around a given axis. The user can either drag the mouse or scroll the wheel, in either cases the rotation's angle is influenced by the radius of the trackball. This is a stateless manipulator, result of the Apply functions is determined only either by the mouse coordinates or by the mouse wheel notch. */ class CylinderMode:public TrackMode { public: /*! @brief The line constructor. This manipulator needs to be initialized with an axis. This constructor can initialize it with a Line3f. The line will be normalized. @param ln the line that represent the axis. @param s a rotational snap angle non negative */ CylinderMode (Line3fN & ln,float s=0.0f) : axis (ln), snap(s){ assert(snap>=0.0); } /*! @brief The origin-direction constructor. This manipulator needs to be initialized with a axis. This constructor can initialize it with two Point3f, representing a point and a vector. @param origin a point on the axis. @param direction the axis direction. @param s a rotational snap angle (non negative) */ CylinderMode (const Point3f & origin, const Point3f & direction,float s=0.0f) : axis (Line3fN(origin,direction)), snap(s){ assert(snap>=0.0); } /*! @brief Return this manipulator's name. @return the constant string "CylinderMode" */ const char *Name () { return "CylinderMode"; }; /*! @brief Apply a rotation, function of the user mouse drag action. The manipulated object is rotated around the axis. if the axis is too perpendicular to view plane, the angle is specified only by the vertical component of the mouse drag and the radius. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ void Apply (Trackball * trackball, Point3f new_point); /*! @brief Apply a rotation, function of the user mouse wheel action. The manipulated object is rotated around the axis. @param trackball the manipulator manager. @param WheelNotch the mouse wheel notch. */ void Apply (Trackball * trackball, float WheelNotch); /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); private: /// The axis, stored as a normalized line. Line3fN axis; /// The rotational snap value float snap; }; // Path mode. /*! @brief The path constrained manipulator. This manipulator moves the object along an eventually closed path. The user can either drag the mouse or scroll the wheel, when the user drags the mouse, the object tries to slide toward it. The object is assumed to initially be on the same position of the first point on the path. This is a \b stateful manipulator, result of the Apply functions is determined by the objects's position along the path and by either the mouse coordinates or the mouse wheel notch. */ class PathMode:public TrackMode { public: /*! @brief The vector-boolean constructor. The vector passed to build the path is copied locally. The boolean value specifies if the path is to be closed. If the boolean value is not specified, the path is not closed. @warning the path is \b not assumed to have 0-length segments, so, if you want to close the path, please do not add a copy of the first point on the end of the vector. @param pts the path nodes. @param w a boolean value that closes the path. */ PathMode ( const std::vector < Point3f > &pts, bool w = false) : points(), wrap(w), current_state(0), initial_state(0), old_hitpoint() { Init(pts); assert(min_seg_length > 0.0f); } /*! @brief The segment constructor. If the path is a simple segment, it can be specified just with the endpoints. @param start the starting point. @param end the ending point. */ PathMode ( const Point3f &start, const Point3f &end ) : points(), wrap(false), current_state(0), initial_state(0), old_hitpoint() { points.push_back(start); points.push_back(end); path_length=Distance(start,end); min_seg_length=path_length; assert(min_seg_length > 0.0f); } /*! @brief Return this manipulator's name. @return the constant string "PathMode" */ const char *Name () { return "PathMode"; }; /*! @brief Apply a translation, function of the user mouse drag action. The manipulated object is moved along the path. This function implements an algorithm that makes the object try to slide on the path towards the mouse pointer. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ void Apply (Trackball * trackball, Point3f new_point); /*! @brief Apply a translation, function of the user mouse wheel action. The manipulated object is moved along the path. A step of the mouse wheel makes the object slide by a distance equal to the half of the shortest segment on the path. @param trackball the manipulator manager. @param WheelNotch the mouse wheel notch. */ void Apply (Trackball * trackball, float WheelNotch); /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); /*! @brief The begin action function. This function is to be called at the begin of an user action. */ void SetAction (); /*! @brief The reset function. This function reset the object position to the initial point. */ void Reset (); /*! @brief Try to set the inital point. This function try to set the starting point in the point passed as parameter, if the point passed does not reside on the path, the start is put on the closest point on it. @param p the point wished for the start. @return the starting point on the path. */ Point3f SetStartNear(Point3f p); /*! @brief The (non) avaibility to manipulator changes inside an action. This manipulator has an internal state and does not allow a switch in the middle of a function. @return the costant boolean true. */ bool isSticky(); /*! @brief The undo function. This function recreates the state present before the last Apply() call. */ void Undo(); private: /*! @brief The data initializer. Initialize the internal state and checks params validity. @param points the path nodes. */ void Init(const std::vector < Point3f > &points); /*! @brief The state interpreter. Given the state, return the current point, the previous node and the next node on the path. The algoritm is linear in the node paths. @param state the given state. @param point is set to the current point. @param prev_point is set to the point of current point's previous node. @param next_point is set to the point of current point's next node. */ void GetPoints(float state, Point3f & point, Point3f & prev_point, Point3f & next_point); /*! @brief The state normalizer. Normalize a given state in the right interval: - \f$ [0 \ldots 1] \f$ if the path is open. - \f$ [0 \ldots 1) \f$ if the path is closed (because it wraps). @param state the given state. */ float Normalize(float state); /*! @brief Compute the new point and the \f$\Delta\f$-state. Given a state and the mouse coords ray, computes the new state point and return the \f$\Delta\f$-state. The algoritm is linear in the node paths. @param state the given state. @param ray the ray relative to mouse coords. @param hit_point is set to the new state point. @return the \f$\Delta\f$-state. */ float HitPoint(float state, Ray3fN ray, Point3f &hit_point); /*! @brief Compute the verse to follow for slide nearer to a given point. Given the current state point, the point of previus and next node and a reference point, compute the verse to follow for the object to come closer to the reference point. @param reference_point @param current_point @param prev_point @param next_point @return -1, 0 or 1 if the verse is respectively towars the startpoint, null or towards the endpoint. */ int Verse(Point3f reference_point,Point3f current_point,Point3f prev_point,Point3f next_point); /// The node vector. std::vector < Point3f > points; /// True if the path is closed, false otherwise. bool wrap; /// The current state. float current_state; /// The initial state. float initial_state; /// The path length. float path_length; /// The length of the shostest path segment float min_seg_length; /// The point relative to the old state. Point3f old_hitpoint; /// current_state after an Undo() call. float undo_current_state; /// old_hitpoint after an Undo() call. Point3f undo_old_hitpoint; }; // Area mode. /*! @brief The area constrained manipulator. This manipulator moves the object inside a poligonal area. The user can drag the object inside a planar area, defined by a polygon. The polygon can be non convex, and is specified with a vector of vertexes. If the object's trajectory intersects some poligon side, it tries to slide around it, in a "rubber band flavoured" way. The object is assumed to initially be on the same position of the first vertex. This is a \b stateful manipulator, result of the Apply function is determined by the objects's position inside the area and by the mouse coordinates. */ class AreaMode:public TrackMode { public: /*! @brief The constructor. From the given vector, is calculated the plane of the polygon, then every point in the vector is projected on this plane. The vector passed to build the polygon is copied locally. @warning The vector is assumed to be formed of \b non collinear points. @warning The polygon is \b not assumed to have 0-length sides, so please do not add a copy of the first point on the end of the vector. @param pts the vertexes vector. */ AreaMode (const std::vector < Point3f > &pts) { Init(pts); assert(min_side_length > 0.0f); } /*! @brief Return this manipulator's name. @return the constant string "AreaMode" */ const char *Name () { return "AreaMode"; }; /*! @brief Apply a translation, function of the user mouse drag action. The manipulated object is moved inside the poligon. This function implements an algorithm that makes the object try to slide around the polygon borders. @param trackball the manipulator manager. @param new_point the new mouse pointer coordinate. */ void Apply (Trackball * trackball, Point3f new_point); /*! @brief Render this manipulator. @param trackball the manipulator manager. */ void Draw (Trackball * trackball); /*! @brief The begin action function. This function is to be called at the begin of an user action. */ void SetAction (); /*! @brief The reset function. This function reset the object position to the initial point. */ void Reset (); /*! @brief Try to set the inital point. This function try to set the starting point in the point passed as parameter, if the point passed does not reside in the area, the start is put in the closest point on it. @param p the point wished for the start. @return the starting point in the area. */ Point3f SetStartNear(Point3f p); /*! @brief The (non) avaibility to manipulator changes inside an action. This manipulator has an internal state and does not allow a switch in the middle of a function. @return The costant boolean true. */ bool isSticky(); /*! @brief The undo function. This function recreates the state present before the last Apply() call. */ void Undo(); private: /*! @brief The data initializer. Initialize the internal state and checks params validity. @param pts The polygon vertexes. */ void Init(const std::vector < Point3f > &pts); /*! @brief Point in Polygon test. Checks if a given point relies inside the poligon area, using the ray tracing algorithm, linear in the number of vertexes. @param point The point to test. @return true if the point is inside the polygon, false otherwise. */ bool Inside(Point3f point); /*! @brief Try to move the object inside the polygon Given a point inside the area and a destination in the poligon plane, try to move the point toward the destination, sliding on any evenual border of the polygon. The object can be imagined tied with a rubber attached to destination, so it won't go back from it to slide around a border. The algorithm is quadratic in the number of vertexes (worst case, really really unlikely). @param start the starting point assumed inside. @param end the destination assumed in the plane. @return the final move vector. */ Point3f Move(Point3f start,Point3f end); /// The vertexes vector. std::vector < Point3f > points; /// True in time inteval between a call to SetAction () and a call to Apply() bool begin_action; /// One of the two dimensions used during the point in polygon test. int first_coord_kept; /// One of the two dimensions used during the point in polygon test. int second_coord_kept; /// The length of the shortest border float min_side_length; /// The current status. Point3f status; /// The screen space differenve between the object and the cursor during an action. Point3f delta_mouse; /// The old status. Point3f old_status; /// The initial status. Point3f initial_status; /// The polygon plane Plane3f plane; /// The rubberband handle (current destination in Move()) Point3f rubberband_handle ; /// Current action's object trace std::vector < Point3f > path; /// begin_action after an Undo() call. bool undo_begin_action; /// status after an Undo() call. Point3f undo_status; /// delta_mouse after an Undo() call. Point3f undo_delta_mouse; /// old_status after an Undo() call. Point3f undo_old_status; /// rubberband_handle after an Undo() call. Point3f undo_rubberband_handle; /// path endpoint after an Undo() call. unsigned int undo_path_index; }; // Polar mode. /* WARNING this mode is not compatible with the other rotation modes */ class PolarMode:public TrackMode { public: PolarMode(): alpha(0), beta(0), enda(0), endb(0) {} void Apply (Trackball * trackball, Point3f new_point); const char *Name () { return "PolarMode"; }; void SetAction(); void Reset(); void Draw (Trackball * trackball); private: float alpha, beta; //rotation in y and x axis float enda, endb; //store intermediate values of alpha and beta }; class NavigatorWasdMode:public TrackMode { public: NavigatorWasdMode(); void Apply (Trackball * trackball, Point3f new_point); const char *Name () { return "NavigatorWasdMode"; }; //void SetAction(); void Reset(); //void Draw (Trackball * trackball); bool isSticky(); bool IsAnimating(const Trackball *tb); void Animate(unsigned int msec, Trackball *tb); void SetAction (); /// specific option setup methods for this mode void FlipH(), FlipV(); // flips mouse controls void SetTopSpeedsAndAcc(float speed_h, float speed_v, float acc=0.0); // (top) speed is in units on sec // Acc is in units on sec^2, if 0 then no-inertia void SetStepOnWalk(float width, float height); // optionally, set step-on-walk effects void Apply (Trackball * trackball, float WheelNotch); private: float alpha, beta; //rotation in y and x axis Point3f current_speed; float step_current, step_last, step_x; int _flipH, _flipV; float accX, accY, accZ, dumping, topSpeedH, topSpeedV; float step_height, step_length; // height of steps }; }//namespace #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gui/frustum.h0000644000175000017500000001501712005675121017742 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.9 2005/03/02 15:13:45 ponchio Minimal fix in remoteness (Bugged anyway) Revision 1.8 2005/02/22 14:33:04 ponchio small bugs Revision 1.7 2005/01/21 18:06:05 ponchio Added remoteness ("distance" from frustum) Revision 1.6 2004/10/04 12:33:02 ponchio Cleaning up and planes init more stable. Revision 1.5 2004/09/28 10:23:28 ponchio Various generic changes. Revision 1.4 2004/05/12 20:55:18 ponchio *** empty log message *** Revision 1.3 2004/03/31 15:06:41 ponchio #include -> #include Revision 1.2 2004/03/25 14:55:25 ponchio Adding copyright. ****************************************************************************/ #ifndef FRUSTUM_H #define FRUSTUM_H #include #include #include #include using namespace std; namespace vcg { template class Frustum: public View { public: void GetView(); void SetView(const float *_proj, const float *_modelview, const int *_viewport); Point3 ViewPoint(); T Resolution(float dist = 1); bool IsOutside(Point3 &point); T Remoteness(Point3 &point, T radius); T IsOutside(Point3 &point, T radius); T Distance(Point3 &point, int plane); T range(Point3 &point, T radius, T &closest, T &farthest); protected: T resolution; Plane3 planes[6]; Point3 view_point; void UpdateView(); }; typedef Frustum Frustumf; typedef Frustum Frustumd; //Implementation template Point3 Frustum::ViewPoint() { return view_point; } template T Frustum::Resolution(float dist) { return resolution * dist; } template bool Frustum::IsOutside(Point3 &point) { Point3 r = Project(point); if(r[0] < View::viewport[0] || r[0] > View::viewport[0]+View::viewport[2] || r[1] < View::viewport[1] || r[1] > View::viewport[1]+View::viewport[3]) return true; return false; } template T Frustum::Remoteness(Point3 &point, T radius) { Point3 r = Project(point); T dist = (point - view_point).Norm(); if(dist < radius) return 0; T rad = 1 + radius / (resolution * dist); T mindist = 0; T tmp; tmp = View::viewport[0] - r[0] - rad; if(tmp > mindist) mindist = tmp; tmp = r[0] - rad - (View::viewport[0] + View::viewport[2]); if(tmp > mindist) mindist = tmp; tmp = View::viewport[1] - r[1] - rad; if(tmp > mindist) mindist = tmp; tmp = r[1] - rad - (View::viewport[1] + View::viewport[3]); if(tmp > mindist) mindist = tmp; if(mindist == 0) return 0; return 1 + (mindist / (View::viewport[0] + View::viewport[2])); } template T Frustum::IsOutside(Point3 &point, T radius) { T dist = 0; for(int i = 0; i < 4; i++) { T d = -Distance(point, i) - radius; if(d > dist) dist = d; } return dist; } template T Frustum::range(Point3 &point, T radius, T &closest, T &farthest) { //4 near 5 far T dist = (view_point - point).Norm(); closest = dist - radius; farthest = dist + radius; } template T Frustum::Distance(Point3 &point, int plane) { return vcg::SignedDistancePlanePoint(planes[plane], point); } template void Frustum::GetView() { View::GetView(); UpdateView(); } template void Frustum::SetView(const float *_proj = NULL, const float *_modelview = NULL, const int *_viewport = NULL) { View::SetView(_proj, _modelview, _viewport); UpdateView(); } template void Frustum::UpdateView() { float t = (float)(View::viewport[1] +View:: viewport[3]); float b = (float)View::viewport[1]; float r = (float)(View::viewport[0] + View::viewport[2]); float l = (float)View::viewport[0]; Point3 nw = UnProject(Point3(l, b, 0.0f)); Point3 sw = UnProject(Point3(l, t, 0.0f)); Point3 ne = UnProject(Point3(r, b, 0.0f)); Point3 se = UnProject(Point3(r, t, 0.0f)); Point3 NW = UnProject(Point3(l, b, 1.0f)); Point3 SW = UnProject(Point3(l, t, 1.0f)); Point3 NE = UnProject(Point3(r, b, 1.0f)); Point3 SE = UnProject(Point3(r, t, 1.0f)); view_point = View::ViewPoint(); planes[0].Init(nw, NW, NE); planes[1].Init(ne, NE, SE); planes[2].Init(se, SE, SW); planes[3].Init(sw, SW, NW); planes[4].Init(se, sw, nw); planes[5].Init(SW, SE, NE); //compute resolution: sizeo of a pixel unitary distance from view_point resolution = ((ne + NE)/2 - (nw + NW)/2).Norm() / (View::viewport[2] * ((ne + NE + nw + NW)/4 - view_point).Norm()); } }//namespace #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gui/coordinateframe.h0000644000175000017500000001660511517500603021402 0ustar gladkgladk/**************************************************************************** * 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.7 2008/03/14 16:54:34 benedetti Added doxygen documentation Revision 1.6 2008/03/02 16:44:18 benedetti moved ActiveCoordinateFrame to its own files 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 ****************************************************************************/ #ifndef COORDINATEFRAME_H #define COORDINATEFRAME_H #include #include #include namespace vcg { /*! @brief The CoordinateFrame class. This class can draw the standard icon for a 3D coordinate frame. */ class CoordinateFrame { public: // functions: /*! @brief The constructor. Initialize the CoordinateFrame data. @param size the distance from the origin to the endpoint of the arrows. */ CoordinateFrame(float size); /*! @brief The destructor. The destructor. */ virtual ~CoordinateFrame() {} /*! @brief Render the coordinate frame. @param glw the GL widget. */ virtual void Render(QGLWidget* glw,QPainter* p = NULL); // data /// The color used for the ticks, the ticks values and the head of the arrows. Color4b basecolor; /// The color of the X axis and label. Color4b xcolor; /// The color of the Y axis and label. Color4b ycolor; /// The color of the Z axis and label. Color4b zcolor; /// The distance from the origin to the endpoint of the arrows. float size; /// The width of the lines. float linewidth; /// The font used for the labels and the ticks values. QFont font; /// The flag that enables axes rendering. bool drawaxis; /// The flag that enables lablels rendering. bool drawlabels; /// The flag that enables ticks values rendering. bool drawvalues; // useful functions: static void drawTickedLine(const Point3d &, const Point3d &, float, float,float); static float calcSlope(const Point3d &, const Point3d &, float, int , double *, double *, GLint *); static float niceRound(float); }; /*! @brief The MovableCoordinateFrame class. This class extends the coordinate frame with the ability of being programmatically rototranslated. */ class MovableCoordinateFrame: public CoordinateFrame { public: /*! @brief The constructor. Initialize the MovableCoordinateFrame data. @param size the distance from the origin to the endpoint of the arrows. */ MovableCoordinateFrame(float); /*! @brief The destructor. The destructor. */ virtual ~MovableCoordinateFrame(){} /*! @brief Render the movable coordinate frame in its position. @param glw the GL widget. */ virtual void Render(QGLWidget* glw); /*! @brief Reset the position and/or the rotation of the coordinate frame. @param reset_position set to true to reset the position. @param reset_alignment set to true to reset the rotation. */ virtual void Reset(bool reset_position,bool reset_alignment); /*! @brief Set the position of the coordinate frame. @param new_position the new position of the coordinate frame. */ virtual void SetPosition(const Point3f new_position); /*! @brief Set the rotation of the coordinate frame. @param new_rotation the new rotation of the coordinate frame. */ virtual void SetRotation(const Quaternionf rotation); /*! @brief Get the position of the coordinate frame. @return the position of the coordinate frame. */ virtual Point3f GetPosition(); /*! @brief Get the rotation of the coordinate frame. @return the rotation of the coordinate frame. */ virtual Quaternionf GetRotation(); /*! @brief Computes the transformation matrix relative to the current rototranslation. @param m is set to the transformation matrix. */ virtual void GetTransform(Matrix44f &m); /*! @brief Rotates the coordinate frame wrt itself. @param angle the angle of the rotation, in degrees. @param axis the axis of the rotation. */ virtual void Rot(float angle,const Point3f axis); /*! @brief Align the coordinate frame to one or two directions. If the primary direction of alignment is null this function does nothing, otherwise two rotations are performed: the first rotation aligns the axis named axis_1 to the primary direction of alignment, the second rotation never moves axis_1 away from the primary direction. If the secondary direction of alignment is not null and is not parallel to the primary direction the axis named axis_2 is rotated as much as possible to be aligned to secondary direction. If the secondary direction of alignment is null the axis named axis_2 is rotated as much as possible to be realigned to its old direction, if this is impossible the remaining axis is used. @param primary the primary direction of alignment. @param secondary the secondary direction of alignment. @param axis_1 the name of the axis to align to the primary direction, must be a char choosen from 'X', 'Y' and 'Z' @param axis_2 the name of the axis to align to the secondary direction, must be different from axis_1 and must be a char choosen from 'X', 'Y', 'Z' and ' '; if the char is ' ' the axis is choosen automatically. */ virtual void AlignWith(const Point3f primary, const Point3f secondary, const char axis_1, const char axis_2); protected: // data: Point3f position; Quaternionf rotation; // functions: virtual void Move(const Similarityf); void RotateToAlign(const Point3f, const Point3f); }; }//namespace #endif /*COORDINATEFRAME_H*/ meshlab-1.3.2+dfsg1/vcglib/wrap/gui/trackball.h0000644000175000017500000004176311517500603020202 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.16 2007/07/14 12:43:44 benedetti Added Doxygen documentation. Revision 1.15 2007/06/13 17:15:08 benedetti Added one-level undo system and sticky trackmodes. Revision 1.14 2007/05/15 15:00:47 benedetti Moved the drawing code to trackmodes, some other minor changes Revision 1.13 2007/02/26 01:30:02 cignoni Added reflection Name Revision 1.12 2007/01/15 15:04:15 tarini added "ToAscii" and "SetFromAscii" methods to load/store current trackball status from/to ascii strings (intended uses: clipboard operations and comments inside png snapshots!) Revision 1.11 2006/08/23 15:40:57 marfr960 *** empty log message *** Revision 1.10 2006/02/13 13:15:52 cignoni Added Scale and Translate methods. Added many drawing hints and raised the default num. of steps when drawing circles. Added MouseDown without coords (for remembering changes of keys modifiers) Added ZMode to the default modes under Alt+left Added DrawPostApply (to be completed) Revision 1.9 2005/10/17 01:29:46 cignoni Main restructuring. Removed the Draw function and slightly changed the meaning of the trackball itself. See the notes at the beginning of trackball.h Revision 1.8 2004/07/11 22:06:56 cignoni Added scaling by wheel Revision 1.7 2004/06/09 14:01:13 cignoni Heavily restructured. To be completed only rotation works... Revision 1.6 2004/05/14 03:15:09 ponchio Redesigned partial version. Revision 1.5 2004/05/12 20:55:18 ponchio *** empty log message *** Revision 1.4 2004/05/07 12:46:08 cignoni Restructured and adapted in a better way to opengl Revision 1.3 2004/04/07 10:54:10 cignoni Commented out unused parameter names and other minor warning related issues Revision 1.2 2004/03/25 14:55:25 ponchio Adding copyright. ****************************************************************************/ #ifndef TRACKBALL_H #define TRACKBALL_H #include #include #include #include #include #include #include #include namespace vcg { /*! @brief The base class for Trackball. This class is useful for using a Trackball instance in a scene graph, as a sort of interactive transform. */ class Transform { public: /*! @brief The constructor. Initialize: - track to the identity transform. - center to origin 0,0,0. - radius to unit size. */ Transform(); /// A trackball stores a transformation called 'track' that effectively rototranslate the object. Similarityf track; /// track position in model space. Point3f center; /// size of the widget in model space. float radius; }; /*! @brief Computes the linear interpolation between 2 transforms. @param a The first transform. @param b The second transform. @param t The interpolation value (0: just a, 0.5: middle from a to b, 1: just b). @return The linear interpolation. */ Transform interpolate(const Transform &a, const Transform &b, float t); class TrackMode; /*! @brief The manipulator manager system. Short usage note: - Center specify the center of rotation and scaling of the trackball and usually is set by the program and do not interactively change - Radius specify the radius of the interactive ball shaped icon to specify rotation. It is in absolute unit. - Like the previous one it is not changed during interaction. When you specify a translation with the trackball the trackball center remain \b unchanged, in other words it means that the object move out of the trackball icon. Similarly when you apply a scaling the size of the manipulator icon do not change. Typical use:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, float(width())/float(height()), 1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,3,   0,0,0,   0,1,0)

trackball.center=Point3f(0, 0, 0);
trackball.radius= 1;

trackball.GetView();
trackball.Apply(true); //false if you want an invisible trackball

float d=1.0f/mesh.bbox.Diag();
glScale(d);
glTranslate(-mesh.bbox.Center());
mesh->Render();
Note on the typical use: - Perspective and glulookat are choosed to frame the origin centered 1-radius trackball. - The final scale and translate are just to fit a generic mesh to the 1sized origin centered where the trackball stays box. - The trackball works also on Orthographic projections \b but that are not centered around origin (just move it back along the Z) */ class Trackball: public Transform { public: /// The componibile states of the manipulator system. enum Button { BUTTON_NONE = 0x0000, ///< No button or key pressed. BUTTON_LEFT = 0x0001, ///< Left mouse button pressed. BUTTON_MIDDLE = 0x0002, ///< Middle mouse button pressed. BUTTON_RIGHT = 0x0004, ///< Right mouse button pressed. WHEEL = 0x0008, ///< Mouse wheel activated. KEY_SHIFT = 0x0010, ///< Shift key pressed. KEY_CTRL = 0x0020, ///< Ctrl key pressed. KEY_ALT = 0x0040, ///< Alt key pressed. HANDLE = 0x0080, ///< Application-defined state activated. MODIFIER_MASK = 0x00FF, ///< (mask to get modifiers only) KEY_UP = 0x0100, ///< Up directional key KEY_DOWN = 0x0200, ///< Down directional key KEY_LEFT = 0x0400, ///< Left directional key KEY_RIGHT = 0x0800, ///< Right directional key KEY_PGUP = 0x1000, ///< PageUp directional key KEY_PGDOWN = 0x2000, ///< PageDown directional key }; /*! @brief The constructor. Initialize the internal state with default values and call setDefaultMapping(). */ Trackball(); /*! @brief The destructor. @warning The destructor does not deallocate the memory allocated by setDefaultMapping(), because the application can change the modes map. This can lead to small memory leaks, so please explicitally delete any manipulator in the modes map if you are going to repeatly allocate and deallocate Trackball instances. */ ~Trackball(); private: // Trackball must not be copied. Use Append (see vcg/complex/trimesh/append.h) Trackball operator =(const Trackball & /*m*/){ assert(0); return *this; } public: /*! @brief Reset the trackball. Equivalent to Reset(). */ void SetIdentity(); /*! @brief Set the position of the trackball. @param c The new position of the trackball. @param millisec Currently not in use. */ void SetPosition(const Point3f &c, int millisec = 0); /*! @brief Currently not in use. @param s Currently not in use. */ void SetScale(const float s) {radius=s;}; /*! @brief Currently not in use. @param transform Currently not in use. @param millisec Currently not in use. */ void SetTransform(const Transform &transform, int millisec = 0); /*! @brief Apply a translation on the current transformation. @param tr The translation vector. */ void Translate(Point3f tr); /*! @brief Apply a scaling on the current transformation. @param f The scale factor. */ void Scale(const float f); //operating /*! @brief Initialize the camera instance. */ void GetView(); /*! @brief Apply the current transformation on the OpenGL modelview matrix. @param Draw true if has to call DrawPostApply() after the application. */ void Apply(bool Draw); /*! @brief Old application of the transformation. @warning This function does \b not call DrawPostApply() after the application. */ void Apply (); /*! @brief Draw the current manipulator. Call the draw function of the current manipulator. If no manipulator is selected call the draw function of the manipulator associated to inactive_mode. @warning This function assumes that the OpenGL modelview matrix has been initialized with Apply (). */ void DrawPostApply(); /*! @brief Apply the \b inverse of current transformation on the OpenGL modelview matrix. */ void ApplyInverse(); // DrawIcon() has been moved to trackutils.h //void DrawIcon(); // T(c) S R T(t) T(-c) => S R T(S^(-1) R^(-1)(c) + t - c) Matrix44f Matrix() const; Matrix44f InverseMatrix() const; /*! @brief Reset the transformation and every mapped manipulator. */ void Reset(); /*! @brief clear the modes map. Taking the right care of not doubledeleting anything. */ void ClearModes(); // DrawCircle (), DrawPlane(), DrawPlaneHandle() has been moved to trackutils.h // the drawing code has been moved to the trackmodes // void DrawCircle (); // void DrawPlane(); // void DrawPlaneHandle(); //interface /*! @brief Interface function relative to mouse down event in QT/SDL. @param button The new state. */ void MouseDown(/*Button*/ int button); /*! @brief Interface function relative to mouse down event in QT/SDL. @param x The horizontal coordinate of the mouse pointer. @param y The vertical coordinate of the mouse pointer. @param button The new state. */ void MouseDown(int x, int y, /*Button*/ int button); /*! @brief Interface function relative to mouse down event in QT/SDL. @param x The horizontal coordinate of the mouse pointer. @param y The vertical coordinate of the mouse pointer. */ void MouseMove(int x, int y); /*! @brief Interface function relative to mouse down event in QT/SDL. @param x The horizontal coordinate of the mouse pointer. @param y The vertical coordinate of the mouse pointer. @param button The new state. */ void MouseUp(int x, int y, /*Button */ int button); /*! @brief Old interface function relative to mouse down event in QT/SDL. @param notch The mouse wheel notch (1: one forward step, -1: one backward step). */ void MouseWheel(float notch); /*! @brief Interface function relative to mouse down event in QT/SDL. @param notch The mouse wheel notch (1: one forward step, -1: one backward step). @param button The new state. */ void MouseWheel (float notch, /*Button */ int button); /*! @brief Interface function relative to key down event in QT/SDL. @param button the new state. */ void ButtonUp(Button button); /*! @brief Interface function relative to key up event in QT/SDL. @param button the new state. */ void ButtonDown(Button button, unsigned int msec=0); /*! @brief Undo function for manipulator system. A call of this function restores the state before last user action. This function calls %Undo() on every mapped manipulator. */ void Undo(); //default sensitivity 1 /*! @brief Currently not in use. @param s Currently not in use. */ void SetSensitivity(float s); void SetSpinnable(bool on); // returns if it is animating or not // bool IsAnimating(unsigned int msec=0); // Animate: either takes an absolute time (if default not specified, then it is automeasured) // or a fixed delta void Animate(unsigned int msec=0); /*! @brief Currently not in use. @return A meaningless boolean value. */ bool IsSpinnable(); /*! @brief Currently not in use. @param spin Currently not in use. */ void SetSpinning(Quaternionf &spin); /*! @brief Currently not in use. */ void StopSpinning(); /*! @brief Currently not in use. @return A meaningless boolean value. */ bool IsSpinning(); //interfaccia navigation: /*! @brief Currently not in use. */ void Back(); /*! @brief Currently not in use. */ void Forward(); /*! @brief Currently not in use. */ void Home(); /*! @brief Currently not in use. */ void Store(); /*! @brief Currently not in use. */ void HistorySize(int lenght); /* //internals // commented out no more used this stuff! enum Action { NONE = 0, VIEW_ROTATE = 1, // Axis Constrained Rotation TRACK_ROTATE_X = 3, TRACK_ROTATE_Y = 4, TRACK_ROTATE_Z = 5, // Drag constrained to an axis (trackball axis) DRAG_X = 6, DRAG_Y = 7, DRAG_Z = 8, // Drag constrained to a plane DRAG_XY = 9, DRAG_YZ = 10, DRAG_XZ = 11, //scale model respect to center of trackball VIEW_SCALE = 12, //scale trackball and model TRACK_SCALE = 13 }; */ // loads stores current status from/to ascii stings /*! @brief Stores current status into an ascii stings Stores current status into an ascii stings. This is useful for example to implement cut-and-paste operations of trackball status, or to embed used trackball into a comment inside a screenshot, etc. @param st The string where to export (must be allocated 256bytes should be enough). */ void ToAscii(char * st); /*! @brief Loads current status from an ascii stings Loads current status from an ascii stings. This is useful for example to implement cut-and-paste operations of trackball status, or to embed used trackball into a comment inside a screenshot, etc. @param st The string where to read from (must be allocated). Use ToAscii() method to set it. @return True iff the trackball was successfully recovered. */ bool SetFromAscii(const char * st); //protected: /// The reference for point projection and unprojection from screen space to modelspace. View camera; /*! @brief Prepare Trackball and every mapped TrackMode for an user action. This function is called automatically when an user action begins. */ void SetCurrentAction(); /// Current state composition. Note: mask with MODIFIERS to get modifier buttons only int current_button; /// The selected manipulator. TrackMode *current_mode; /// The inactive manipulator. It is drawn when Trackball is inactive. TrackMode *inactive_mode; // The manipulator to deal with timer events and key events TrackMode *idle_and_keys_mode; /*! @brief Reset modes to default mapping. Set the default modes mapping. The default mapping is: - \b LEFT : SphereMode. - \b LEFT+CTRL or \b MIDDLE : PanMode. - \b LEFT+SHIFT or \b WHEEL : ScaleMode. - \b LEFT+ALT : ZMode. @warning The memory allocated by this function is not automatically deallocated. see ~Trackball(). */ void setDefaultMapping (); /// The manipulator mapping. Needs to be explicitally managed for custom mappings. std::map modes; // undo_track and last_track have different meanings.. /// Transformation before current user action. Similarityf last_track; /// track after an Undo() call. Similarityf undo_track; /// Currently not in use. Similarityf last_view; /// Mouse cursor coordinates before current action. Point3f last_point; /// Currently not in use. std::vector Hits; /// Currently not in use. bool dragging; /// Currently not in use. int button_mask; unsigned int last_time; /// Currently not in use. Quaternionf spin; /// Currently not in use. bool spinnable; /// Currently not in use. bool spinning; /// Currently not in use. std::list history; /// Currently not in use. int history_size; void SetFixedTimesteps(bool mode){ fixedTimestepMode=mode; } /// Manipulators needs full access to this class. friend class TrackMode; private: void Sync(unsigned int msec); bool fixedTimestepMode; // if true, animations occurs at fixed time steps }; }//namespace #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gui/view.h0000644000175000017500000001727711644553163017232 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.15 2007/01/18 01:24:32 cignoni Added cast for mac compiling Revision 1.14 2005/10/15 15:23:32 ponchio Fixed viewport<->window coordinate change for the z. (z = 2*z -1 now) Accordingly to gluUnproject documentation. Revision 1.13 2005/02/11 11:53:18 tommyfranken changed pointf to point in ViewLineFromWindow Revision 1.12 2005/02/10 20:09:11 tarini dispelled the mega-evil of GL_TRANSPOSE_*_MATRIX_ARB Revision 1.11 2005/01/19 10:29:45 cignoni Removed the inclusion of a glext.h Revision 1.10 2005/01/18 16:47:42 ricciodimare *** empty log message *** Revision 1.9 2004/09/28 10:22:00 ponchio Added #include Revision 1.8 2004/05/26 15:15:46 cignoni Removed inclusion of gl extension stuff Revision 1.7 2004/05/14 03:15:40 ponchio Added ViewLineFromModel Revision 1.6 2004/05/12 20:55:18 ponchio *** empty log message *** Revision 1.5 2004/05/07 12:46:08 cignoni Restructured and adapted in a better way to opengl Revision 1.4 2004/04/07 10:54:11 cignoni Commented out unused parameter names and other minor warning related issues Revision 1.3 2004/03/31 15:07:37 ponchio CAMERA_H -> VCG_CAMERA_H Revision 1.2 2004/03/25 14:55:25 ponchio Adding copyright. ****************************************************************************/ #ifndef __VCGLIB_WRAP_GUI_VIEW_H #define __VCGLIB_WRAP_GUI_VIEW_H /********************** WARNING Everything here assumes the opengl window coord system. the 0,0 is bottom left y is upward! **********************/ #include #include #include #include #include #ifdef WIN32 #include #endif #if defined(__APPLE__) #include #else #include #endif namespace vcg { /** This class represent the viewing parameters under opengl. Mainly it stores the projection and modelview matrix and the viewport and it is used to simply project back and forth points, computing line of sight, planes etc. Note: mainly it is used only by the TrackBall. */ template class View { public: void GetView(); void SetView(const float *_proj, const float *_modelview, const int *_viewport); Point3 Project(const Point3 &p) const; Point3 UnProject(const Point3 &p) const; Point3 ViewPoint() const; /// Return the plane perpendicular to the view axis and passing through point P. Plane3 ViewPlaneFromModel(const Point3 &p); /// Return the line of view passing through point P. Line3 ViewLineFromModel(const Point3 &p); /// Return the line passing through the point p and the observer. Line3 ViewLineFromWindow(const Point3 &p); /// Convert coordinates from the range -1..1 of Normalized Device Coords to range 0 viewport[2] Point3 NormDevCoordToWindowCoord(const Point3 &p) const; /// Convert coordinates from 0--viewport[2] to the range -1..1 of Normalized Device Coords to Point3 WindowCoordToNormDevCoord(const Point3 &p) const; Matrix44 proj; Matrix44 model; Matrix44 matrix; Matrix44 inverse; int viewport[4]; }; template void View::GetView() { glGetv(GL_PROJECTION_MATRIX,proj); glGetv(GL_MODELVIEW_MATRIX,model); glGetIntegerv(GL_VIEWPORT, (GLint*)viewport); matrix = proj*model; inverse = matrix; Invert(inverse); } template void View::SetView(const float *_proj, const float *_modelview, const int *_viewport) { for(int i = 0; i < 4; i++) { for(int k =0; k < 4; k++) { proj[i][k] = _proj[4*i+k]; model[i][k] = _modelview[4*i+k]; } viewport[i] = _viewport[i]; } matrix = proj*model; inverse = matrix; Invert(inverse); } template Point3 View::ViewPoint() const { Matrix44 mi=model; Invert(mi); return mi* Point3(0, 0, 0); } // Note that p it is assumed to be in model coordinate. template Plane3 View::ViewPlaneFromModel(const Point3 &p) { //compute normal, pointing away from view. Matrix44 imodel = model; Invert(imodel); Point3 vp=ViewPoint(); vcg::Point3f n = imodel * vcg::Point3(0.0f, 0, -1.0f) - vp; Plane3 pl; pl.Init(p, n); return pl; } // Note that p it is assumed to be in model coordinate. template Line3 View::ViewLineFromModel(const Point3 &p) { Point3 vp=ViewPoint(); Line3 line; line.SetOrigin(vp); line.SetDirection(p - vp); return line; } // Note that p it is assumed to be in window coordinate. template Line3 View::ViewLineFromWindow(const Point3 &p) { Line3 ln; // plane perpedicular to view direction and passing through manip center Point3 vp=ViewPoint(); Point3 pp=UnProject(p); ln.SetOrigin(vp); ln.SetDirection(pp-vp); return ln; } template Point3 View::Project(const Point3 &p) const { Point3 r; r = matrix * p; return NormDevCoordToWindowCoord(r); } template Point3 View::UnProject(const Point3 &p) const { Point3 s = WindowCoordToNormDevCoord(p); s = inverse * s ; return s; } // Come spiegato nelle glspec // dopo la perspective division le coordinate sono dette normalized device coords ( NDC ). // Per passare alle window coords si deve fare la viewport transformation. // Le coordinate di viewport stanno tra -1 e 1 template Point3 View::NormDevCoordToWindowCoord(const Point3 &p) const { Point3 a; a[0] = (p[0]+1)*(viewport[2]/(T)2.0)+viewport[0]; a[1] = (p[1]+1)*(viewport[3]/(T)2.0)+viewport[1]; //a[1] = viewport[3] - a[1]; a[2] = (p[2]+1)/2; return a; } template Point3 View::WindowCoordToNormDevCoord(const Point3 &p) const { Point3 a; a[0] = (p[0]- viewport[0])/ (viewport[2]/(T)2.0) - 1; a[1] = (p[1]- viewport[1])/ (viewport[3]/(T)2.0) - 1; //a[1] = -a[1]; a[2] = 2*p[2] - 1; return a; } }//namespace #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gui/rubberband.cpp0000644000175000017500000001607711517500603020704 0ustar gladkgladk/**************************************************************************** * 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 #include #include #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(13); } 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); glDisable(GL_DEPTH_TEST); 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); glGetError();//Due to buggy glrenderText() 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); } meshlab-1.3.2+dfsg1/vcglib/wrap/gui/trackmode.cpp0000644000175000017500000006036211732414757020560 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ #include #include #include #include #include using namespace vcg; using namespace vcg::trackutils; // Track mode implementation, dummy. void TrackMode::Apply (Trackball * , float ){} void TrackMode::Apply (Trackball * , Point3f ){} void TrackMode::Draw(Trackball * ){} void TrackMode::SetAction (){} void TrackMode::Reset (){} bool TrackMode::IsAnimating(const Trackball *){ return false; } void TrackMode::Animate(unsigned int, Trackball *){ } bool TrackMode::isSticky() { return false; } void TrackMode::Undo(){} // draw an inactive trackball void InactiveMode::Draw(Trackball * tb){ DrawSphereIcon(tb,false); } // Sphere mode implementation. // the most important function; given a new point in window coord, // it update the transformation computed by the trackball. // General scheme : the transformation is a function of just // the begin and current mouse positions, with greater precision // is function of just two 3d points over the manipulator. void SphereMode::Apply (Trackball * tb, Point3f new_point) { Point3f hitOld = HitSphere (tb, tb->last_point); Point3f hitNew = HitSphere (tb, new_point); tb->Hits.push_back (hitNew); Point3f center = tb->center; Point3f axis = (hitNew - center) ^ (hitOld - center); // Figure out how much to rotate around that axis. float phi = Distance (hitNew, hitOld) / tb->radius; // tb->track.rot = tb->last_track.rot * Quaternionf (-phi, axis); tb->track.rot = Quaternionf (-phi, axis) * tb->last_track.rot; } void SphereMode::Draw(Trackball * tb){ DrawSphereIcon(tb,true ); } // Pan mode implementation. void PanMode::Apply (Trackball * tb, Point3f new_point) { Point3f hitOld = HitViewPlane (tb, tb->last_point); Point3f hitNew = HitViewPlane (tb, new_point); tb->Translate (hitNew - hitOld); } void PanMode::Draw(Trackball * tb){ DrawSphereIcon(tb,true ); DrawUglyPanMode(tb); } // Z mode implementation. void ZMode::Apply (Trackball * tb, float WheelNotch) { Point3f dir= (GetViewPlane (tb->camera, tb->center)).Direction(); dir.Normalize(); tb->Translate (dir * (-WheelNotch)); } void ZMode::Apply (Trackball * tb, Point3f new_point) { Point3f dir= (GetViewPlane (tb->camera, tb->center)).Direction(); dir.Normalize(); tb->Translate (dir * ( -2.0f * getDeltaY(tb,new_point))); } void ZMode::Draw(Trackball * tb){ DrawSphereIcon(tb,true ); DrawUglyZMode(tb); } // Scale mode implementation. void ScaleMode::Apply (Trackball * tb, float WheelNotch) { tb->track.sca *= pow (1.2f, -WheelNotch); } void ScaleMode::Apply (Trackball * tb, Point3f new_point) { tb->track.sca = tb->last_track.sca * pow (3.0f, -(getDeltaY(tb,new_point))); } void ScaleMode::Draw(Trackball * tb){ DrawSphereIcon(tb,true ); DrawUglyScaleMode(tb); } // Axis mode implementation. void AxisMode::Apply (Trackball * tb, float WheelNotch) { tb->Translate (axis.Direction () * (WheelNotch / 10.0f)); } void AxisMode::Apply (Trackball * tb, Point3f new_point) { std::pair< Point3f,bool > hitOld = HitNearestPointOnAxis (tb, axis, tb->last_point); std::pair< Point3f,bool > hitNew = HitNearestPointOnAxis (tb, axis, new_point); if (hitOld.second && hitNew.second){ tb->Translate (hitNew.first - hitOld.first); } } void AxisMode::Draw(Trackball * tb){ DrawSphereIcon(tb,true ); DrawUglyAxisMode(tb,axis); } // Plane mode implementation. void PlaneMode::Apply (Trackball * tb, Point3f new_point) { std::pair< Point3f, bool > hitOld = HitPlane(tb,tb->last_point,plane); std::pair< Point3f, bool > hitNew = HitPlane(tb,new_point,plane); if(hitOld.second && hitNew.second){ tb->Translate (hitNew.first - hitOld.first); } } void PlaneMode::Draw(Trackball * tb){ DrawSphereIcon(tb,true ); DrawUglyPlaneMode(tb, plane); } // Cylinder mode implementation. void CylinderMode::Apply (Trackball * tb, float WheelNotch) { const float PI2=6.283185307179586232f; float angle= (snap==0.0) ? WheelNotch/(tb->radius * PI2) : WheelNotch * snap; tb->track.rot = tb->last_track.rot * Quaternionf (angle,axis.Direction()); } void CylinderMode::Apply (Trackball * tb, Point3f new_point) { Plane3f viewplane=GetViewPlane (tb->camera, tb->center); Line3f axisproj; axisproj=ProjectLineOnPlane(axis,viewplane); float angle; const float EPSILON=0.005f; // this IS scale independent if(axisproj.Direction().Norm() < EPSILON){ angle=(10.0f * getDeltaY(tb,new_point)) / tb->radius; } else { Point3f hitOld = HitViewPlane (tb, tb->last_point); Point3f hitNew = HitViewPlane (tb, new_point); axisproj.Normalize(); Point3f plusdir= viewplane.Direction() ^ axisproj.Direction(); float distOld = signedDistance(axisproj,hitOld,plusdir); float distNew = signedDistance(axisproj,hitNew,plusdir); angle= (distNew-distOld) / tb->radius; } if(snap>0.0){ angle = ((angle<0)?-1:1)* floor((((angle<0)?-angle:angle)/snap)+0.5f)*snap; } // tb->track.rot = tb->last_track.rot * Quaternionf (angle,axis.Direction()); tb->track.rot = Quaternionf (-angle,axis.Direction()) * tb->last_track.rot; } void CylinderMode::Draw(Trackball * tb){ DrawSphereIcon(tb,true ); DrawUglyCylinderMode(tb,axis); } // Path mode implementation. void PathMode::Init(const std::vector < Point3f > &pts) { unsigned int npts = int(pts.size()); assert(npts >= 2); points.reserve(npts); for(unsigned int i=0;i(Segment3f(p0,p1),point,segment_point,distance); // float distance=Distance(segment_point,point); if(distance= 0.0 ); if(nearest_state > 1.0){ nearest_state=1.0; nearest_point=( wrap ? points[0] : points[npts-1] ); } initial_state=nearest_state; return nearest_point; } void PathMode::GetPoints(float state, Point3f & point, Point3f & prev_point, Point3f & next_point) { assert(state >= 0.0f); assert(state <= 1.0f); float remaining_norm=state; Point3f p0(0,0,0),p1(0,0,0); unsigned int npts = int(points.size()); for(unsigned int i = 1;i <= npts;i++){ if( i == npts){ if (wrap){ p0=points[npts-1]; p1=points[0]; } else { break; } } else { p0=points[i-1]; p1=points[i]; } float segment_norm= Distance(p0,p1) / path_length; if (segment_norm < remaining_norm){ remaining_norm -= segment_norm; continue; } prev_point = p0; next_point = p1; float ratio= remaining_norm / segment_norm; point = prev_point + (( next_point - prev_point ) * ratio); const float EPSILON=min_seg_length * 0.01f; if(Distance(point,prev_point) < EPSILON){ point=prev_point; if (i > 1){ prev_point=points[i-2]; } else if (wrap){ prev_point=points[npts-1]; } } else if (Distance(point,next_point) < EPSILON){ point=next_point; if( i < (npts-1)){ next_point=points[i+1]; } else { if (wrap){ next_point=points[1]; } else { next_point=points[npts-1]; } } } return; } // rounding errors can lead out of the for.. prev_point = p0; point = p1; if (wrap){ next_point=points[1]; }else{ next_point = points[npts-1]; } } void PathMode::Apply (Trackball * tb, float WheelNotch) { undo_current_state=current_state; undo_old_hitpoint=old_hitpoint; const float STEP_COEFF = min_seg_length * 0.5f; float delta=(WheelNotch*STEP_COEFF)/path_length; Point3f old_point,new_point,prev_point,next_point; GetPoints(current_state,old_point,prev_point,next_point); current_state=Normalize(current_state+delta); GetPoints(current_state,new_point,prev_point,next_point); tb->Translate (new_point - old_point); } float PathMode::Normalize(float state) { if ( wrap ) { double intpart; float fractpart; fractpart =(float) modf(state,&intpart); if( fractpart < 0.0f ) fractpart += 1.0f; return fractpart; } if ( state < 0.0f ) return 0.0f; if ( state > 1.0f ) return 1.0f; return state; } int PathMode::Verse(Point3f reference_point,Point3f current_point,Point3f prev_point,Point3f next_point) { Point3f reference_dir = reference_point - current_point ; Point3f prev_dir = prev_point - current_point ; Point3f next_dir = next_point - current_point ; const float EPSILON=min_seg_length * 0.005f; if (reference_dir.Norm() < EPSILON) reference_dir = Point3f(0,0,0); if (prev_dir.Norm() < EPSILON) prev_dir = Point3f(0,0,0); if (next_dir.Norm() < EPSILON) next_dir = Point3f(0,0,0); reference_dir.Normalize(); prev_dir.Normalize(); next_dir.Normalize(); float prev_coeff,next_coeff; prev_coeff = prev_dir.dot(reference_dir); next_coeff = next_dir.dot(reference_dir); if (prev_coeff < 0.0f) prev_coeff = 0.0f; if (next_coeff < 0.0f) next_coeff = 0.0f; if( (prev_coeff == 0.0f) && (next_coeff == 0.0f)){ return 0; } if ( prev_coeff <= next_coeff ){ return 1; } return -1; } float PathMode::HitPoint(float state, Ray3fN ray, Point3f &hit_point) { Point3f current_point, next_point, prev_point; GetPoints(state,current_point,prev_point,next_point); Point3f closest_point; closest_point=ray.ClosestPoint(current_point); int verse=Verse(closest_point,current_point,prev_point,next_point); if (verse == 0){ hit_point=current_point; return 0.0f; } Segment3f active_segment; if (verse > 0){ active_segment=Segment3f(current_point,next_point); } else { active_segment= Segment3f(current_point,prev_point); } //hit_point=ClosestPoint(active_segment,closest_point); float dist; vcg::SegmentPointDistance(active_segment,closest_point,hit_point,dist); return verse * ((hit_point-current_point).Norm() / path_length); } void PathMode::SetAction (){ Point3f temp1,temp2; GetPoints(current_state,old_hitpoint,temp1,temp2); } void PathMode::Apply (Trackball * tb, Point3f new_point) { undo_current_state=current_state; undo_old_hitpoint=old_hitpoint; Ray3fN ray = line2ray(tb->camera.ViewLineFromWindow (new_point)); Point3f hit_point; float delta_state=HitPoint(current_state,ray,hit_point); current_state=Normalize(current_state+delta_state); tb->Translate (hit_point - old_hitpoint); } bool PathMode::isSticky() { return true; } void PathMode::Undo(){ current_state=undo_current_state; old_hitpoint=undo_old_hitpoint; } void PathMode::Draw(Trackball * tb){ DrawSphereIcon(tb,true ); Point3f current_point,prev_point,next_point; GetPoints(current_state,current_point,prev_point,next_point); DrawUglyPathMode(tb,points,current_point,prev_point, next_point,old_hitpoint,wrap); } // Area mode implementation. void AreaMode::Init(const std::vector < Point3f > &pts) { unsigned int npts = int(pts.size()); assert(npts >= 3); //get the plane Point3f p0=pts[0]; unsigned int onethird=(unsigned int)floor(npts/3.0); const float EPSILON = 0.005f; bool pts_not_in_line=false; Point3f a,b; for(unsigned int i=0;i EPSILON; if(pts_not_in_line){ plane.Init( pts[i%npts], pts[(i+(onethird))%npts], pts[(i+(2*onethird))%npts]); break; } } assert(pts_not_in_line); float ncx,ncy,ncz; ncx=fabs(plane.Direction()[0]); ncy=fabs(plane.Direction()[1]); ncz=fabs(plane.Direction()[2]); if(( ncx > ncy ) && ( ncx > ncz )){ first_coord_kept=1; second_coord_kept=2; } else if(( ncy > ncx ) && ( ncy > ncz)){ first_coord_kept=0; second_coord_kept=2; } else { first_coord_kept=0; second_coord_kept=1; } points.reserve(npts); for(unsigned int i=0;icamera.Project(status)-new_point; begin_action=false; } std::pair< Point3f, bool > hitNew = HitPlane(tb,new_point+delta_mouse,plane); if(! hitNew.second){ return; } Point3f hit_point=hitNew.first; Point3f delta_status=Move(status,hit_point); status += delta_status; tb->Translate (status - old_status); rubberband_handle=hit_point; } void AreaMode::SetAction () { begin_action=true; old_status=status; path.clear(); path.push_back(status); rubberband_handle=status; } Point3f AreaMode::Move(Point3f start,Point3f end) { const float EPSILON=min_side_length*0.001f; Point3f pt=start; bool done=false; bool end_inside=Inside(end); while(!done){ path.push_back(pt); Segment3f segment(pt,end); bool p_on_side = false; bool hit=false; Point3f pside(0,0,0),phit(0,0,0); bool slide=false,mid_inside=false; int np = int(points.size()), i, j; for (i = 0, j = np-1; i < np; j = i++) { Segment3f side(points[i],points[j]); Point3f pseg,psid; //std::pair res=SegmentSegmentDistance(segment,side,pseg,psid); std::pair res; vcg::SegmentSegmentDistance(segment,side,res.first,res.second,pseg,psid); if(res.first < EPSILON && ! res.second){ float dist= Distance(pt,pseg); if(dist < EPSILON){ //Point3f pn=ClosestPoint(side,end); Point3f pn; float dist; vcg::SegmentPointDistance(side,end,pn,dist); if(!p_on_side || (Distance(pn,end) EPSILON; if (hit) mid_inside = Inside( pt + ( ( phit - pt ) / 2) ); if ( !hit && end_inside ){ pt = end; done = true; } else if ( hit && (!p_on_side || (p_on_side && mid_inside))) { pt = phit; } else if ( p_on_side && slide) { pt = pside; } else { done = true; } } path.push_back(pt); return pt - start; } // adapted from the original C code by W. Randolph Franklin // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html bool AreaMode::Inside(Point3f point) { bool inside=false; float x=point[first_coord_kept]; float y=point[second_coord_kept]; float yi, yj, xi, xj; int i, j, np=int(points.size()); for (i = 0, j = np-1; i < np; j = i++) { xi=points[i][first_coord_kept]; yi=points[i][second_coord_kept]; xj=points[j][first_coord_kept]; yj=points[j][second_coord_kept]; if ( ( ( (yi<=y) && (y(side,candidate,side_point,distance); if( distance < nearest_distance ){ nearest_point=side_point; nearest_distance=distance; } } initial_status=nearest_point; return initial_status; } bool AreaMode::isSticky() { return true; } void AreaMode::Undo(){ begin_action=undo_begin_action; status=undo_status; delta_mouse=undo_delta_mouse; old_status=undo_old_status; rubberband_handle=undo_rubberband_handle; for(unsigned int i=path.size() - 1; i > undo_path_index; --i) path.pop_back(); } void AreaMode::Draw(Trackball * tb) { DrawSphereIcon(tb,true ); DrawUglyAreaMode(tb,points,status,old_status,plane,path,rubberband_handle); } // Polar mode implementation. void PolarMode::Apply (Trackball * tb, Point3f new_point) { Point3f hitOld = HitViewPlane (tb, tb->last_point); Point3f hitNew = HitViewPlane (tb, new_point); float dx = (hitNew.X() - hitOld.X()); float dy = (hitNew.Y() - hitOld.Y()); const float scale = float(0.5*M_PI); //sensitivity of the mouse const float top = float(0.9*M_PI/2); //maximum top view angle float anglex = dx/(tb->radius * scale); float angley = -dy/(tb->radius * scale); enda = alpha + anglex; endb = beta + angley; if(endb > top) endb = top; if(endb < -top) endb = -top; tb->track.rot = Quaternionf (endb, Point3f(1,0,0)) * Quaternionf (enda, Point3f(0,1,0)) ; } void PolarMode::SetAction() { alpha = enda; beta = endb; } void PolarMode::Reset() { alpha = beta = enda = endb = 0; } void PolarMode::Draw(Trackball * tb){ DrawSphereIcon(tb,true ); } // Navigator WASD implementation NavigatorWasdMode::NavigatorWasdMode() { _flipH=1; _flipV=1; SetTopSpeedsAndAcc(1,1,4); step_height = step_length = 0; Reset(); }; void NavigatorWasdMode::Reset() { alpha=0; beta=0; current_speed.SetZero(); step_x=0.0f; step_current = step_last = 0.0; } void NavigatorWasdMode::FlipH(){ _flipH*=-1; } void NavigatorWasdMode::FlipV(){ _flipV*=-1; } void NavigatorWasdMode::SetAction() { } bool NavigatorWasdMode::IsAnimating(const Trackball * tb){ const unsigned int MOVEMENT_KEY_MASK = (const unsigned int)(~Trackball::MODIFIER_MASK); if (tb->current_button & MOVEMENT_KEY_MASK) return true; if (current_speed!=Point3f(0,0,0)) return true; if (step_current>0.0) return true; return false; } void NavigatorWasdMode::Animate(unsigned int msec, Trackball * tb){ vcg::Point3f acc(0,0,0); float sa = sin(-alpha); float ca = cos(-alpha); if (tb->current_button & Trackball::KEY_UP ) acc += vcg::Point3f( sa,0,ca)*(accY*_flipH); if (tb->current_button & Trackball::KEY_DOWN ) acc -= vcg::Point3f( sa,0,ca)*(accY*_flipH); if (tb->current_button & Trackball::KEY_LEFT ) acc -= vcg::Point3f(-ca,0,sa)*accX; if (tb->current_button & Trackball::KEY_RIGHT ) acc += vcg::Point3f(-ca,0,sa)*accX; if (tb->current_button & Trackball::KEY_PGUP ) acc -= vcg::Point3f( 0,1, 0)*accZ; if (tb->current_button & Trackball::KEY_PGDOWN) acc += vcg::Point3f( 0,1, 0)*accZ; float sec = msec/1.0f; current_speed += acc*sec; tb->track.tra+=current_speed*sec; // compute step height. Point3f current_speed_h = current_speed; current_speed_h[1]=0; float vel = current_speed_h.Norm(); if (veltrack.tra[1]+=step_last; tb->track.tra[1]-=step_current; step_last=step_current; //tb->track.tra[1]+=0.01; } void NavigatorWasdMode::Apply (Trackball * tb, Point3f new_point) { Point3f hitOld = tb->last_point; Point3f hitNew = new_point; tb->last_point=new_point; float dx = (hitNew.X() - hitOld.X()); float dy = (hitNew.Y() - hitOld.Y()); const float scale = float(150*M_PI); //sensitivity of the mouse const float top = float(0.9f*M_PI/2); //maximum top view angle float anglex = dx/(tb->radius * scale); float angley = -dy/(tb->radius * scale * 0.5f); alpha+= anglex*_flipH; beta += angley*_flipV; if(beta > +top) beta = +top; if(beta < -top) beta = -top; Point3f viewpoint = tb->track.InverseMatrix()*Point3f(0,0,0); tb->track.tra = tb->track.rot.Inverse().Rotate(tb->track.tra + viewpoint ) ; tb->track.rot = Quaternionf (beta , Point3f(1,0,0)) * Quaternionf (alpha, Point3f(0,1,0)) ; tb->track.tra = tb->track.rot.Rotate(tb->track.tra) - viewpoint ; tb->track.tra[1]+=step_last; tb->track.tra[1]-=step_current; step_last=step_current; } void NavigatorWasdMode::SetTopSpeedsAndAcc(float hspeed, float vspeed, float acc){ // conversion to msec hspeed /= 1000; vspeed /= 1000; acc /= 1000000; accX = accY = acc; dumping = hspeed / ( hspeed + acc ); accZ = ( vspeed / dumping ) - vspeed; if (acc==0) { accX = accY = hspeed; accZ = vspeed; dumping=0.0; } topSpeedH = hspeed; topSpeedV=vspeed; } void NavigatorWasdMode::SetStepOnWalk(float width, float height){ step_length = width; step_height = height; } void NavigatorWasdMode::Apply (Trackball * tb, float WheelNotch) { tb->Translate(Point3f(0,topSpeedV,0)*(-WheelNotch*100)); } bool NavigatorWasdMode::isSticky(){ return false; } meshlab-1.3.2+dfsg1/vcglib/wrap/io_edgemesh/0000755000175000017500000000000012227522351017546 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/wrap/io_edgemesh/export_dxf.h0000644000175000017500000000672511517500606022113 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.4 2005/02/03 11:22:34 spinelli ricorretti i metodi save per rendere compatibile il formato dxf con il formato di autocad specificato nel dxf reference 2005 Revision 1.3 2004/07/02 17:08:12 ganovelli created Revision 1.2 2004/06/10 15:15:16 ganovelli changes to comply dxf specs Revision 1.1 2004/05/27 13:24:08 ganovelli export_dxf created ****************************************************************************/ #ifndef __VCG_LIB_EXPORTER_DXF #define __VCG_LIB_EXPORTER_DXF namespace vcg { namespace edg { namespace io { template class ExporterDXF { public: ExporterDXF(void){} static bool Save(EdgeMeshType *mp, const char * filename) { FILE * o = fopen(filename,"w"); if(o==NULL) return false; fprintf(o,"0\n"); fprintf(o,"SECTION\n"); fprintf(o,"2\n"); fprintf(o,"ENTITIES\n"); Save(mp,o); fprintf(o,"0\n"); fprintf(o,"ENDSEC\n"); fprintf(o,"0\n"); fprintf(o,"EOF\n"); fclose(o); return true; } static void Save(EdgeMeshType *mp, FILE* o ) { typename EdgeMeshType::EdgeIterator i; for(i=mp->edges.begin(); i!=mp->edges.end();++i) { Point3f p1 = (*i).V(0)->P(); Point3f p2 = (*i).V(1)->P(); fprintf(o,"0\n"); fprintf(o,"LINE\n"); fprintf(o,"8\n"); fprintf(o,"0\n"); fprintf(o,"10\n"); fprintf(o,"%f\n", p1[0]); //X fprintf(o,"20\n"); fprintf(o,"%f\n", p1[1]); //Y fprintf(o,"30\n"); fprintf(o,"%f\n", p1[2]); //Z fprintf(o,"11\n"); fprintf(o,"%f\n", p2[0]); //X fprintf(o,"21\n"); fprintf(o,"%f\n", p2[1]); //Y fprintf(o,"31\n"); fprintf(o,"%f\n", p2[2]); //Z } } }; }; }; }; #endif meshlab-1.3.2+dfsg1/vcglib/wrap/io_edgemesh/export_svg.h0000644000175000017500000001725111551320500022114 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2006 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef __VCG_LIB_EXPORTER_SVG #define __VCG_LIB_EXPORTER_SVG namespace vcg { namespace tri { namespace io { /** * SVG Properties. * * Support class to set the properties of the SVG exporter. */ class SVGProperties { // definitions public: // When multiple meshes are passed, they are arranged in a grid according these two values. // the default is two column and enough row. If numRow is not sufficient it is automatically enlarged. int numCol; int numRow; Point2f sizeCm; // The size, in the drawing, of each ViewBox (in cm) Point2f marginCm; // how much space between each slice box (in cm) Point2f pageSizeCm() // This is automatically computed from the above values { float xSize = numCol*sizeCm[0] + numCol*marginCm[0] + marginCm[0]; float ySize = numRow*sizeCm[1] + numRow*marginCm[1] + marginCm[1]; return Point2f(xSize,ySize); } Point3f projDir; // Direction of the Projection Point3f projUp; Point3f projCenter; // the 3d point that after projection will fall exactly in the center of the ViewBox. // How the mesh will be scaled. // if this value is 0 the bounding box of all the passed meshes will be used to compute the scale and center // otherwise it is a scaling factor that is used to place the mesh in a unit cube (-1..1) // usually it is 2/bbox.Diag float scale; // SVG Style Parameters int lineWidthPt; // Line width. std::string strokeColor; // Stroke color (see StrokeColor). std::string strokeLineCap;// Stroke linecap (see StrokeLineCap). //Text details bool showTextDetails; public: SVGProperties() { lineWidthPt = 1; strokeColor = "black"; strokeLineCap = "round"; // default projection (XZ plane with the z up) projDir= Point3f(0.0, 1.0, 0.0); projUp = Point3f(0.0, 0.0, 1.0); scale=0; //viewBox=Point2f(10, 10); projCenter=Point3f(0, 0, 0); sizeCm=Point2f(10,10); marginCm=Point2f(1,1); showTextDetails=true; numCol=2; numRow=10; } }; /** * SVG exporter. * * This exporter save a mesh of EdgeMesh type in the SVG format. * Most of the features of the SVG format are not supported. * The given EdgeMesh is saved as a set lines. The properties * of the SVG export can be set through the SVGProp class. */ template class ExporterSVG { public: // Standard saving Function // just a wrapper to the below static bool Save(EdgeMeshType &m, const char *filename, SVGProperties & pro) { std::vector MeshVec; MeshVec.push_back(&m); return Save(MeshVec,filename,pro); } // Main saving function // save a Multiple Set of Edge Meshes on a single SVG files static bool Save(std::vector &meshVec, const char *filename, SVGProperties & pro) { FILE * fpo = fopen(filename,"w"); if (fpo==NULL) return false; WriteXmlHead(fpo, pro); for(size_t i=0;i"); fclose(fpo); return true; } static void WriteXmlHead(FILE *o, SVGProperties & pro) { fprintf(o, "\n"); fprintf(o, "\n"); fprintf(o, " \n"); fprintf(o, " \n"); fprintf(o, " \n"); fprintf(o, " \n"); fprintf(o, " \n"); fprintf(o, " image/svg+xml \n"); fprintf(o, " \n"); fprintf(o, " \n"); fprintf(o, " \n"); fprintf(o, " \n \n"); } static void WriteXmlBody(FILE* fpo, EdgeMeshType &mp, SVGProperties &pro, int meshIndex) { int rowInd = meshIndex / pro.numCol; int colInd = meshIndex % pro.numCol; fprintf(fpo, " \n", pro.sizeCm[0], pro.sizeCm[1], pro.marginCm[0]+colInd*(pro.sizeCm[0]+pro.marginCm[0]), pro.marginCm[1]+rowInd*(pro.sizeCm[1]+pro.marginCm[1])); fprintf(fpo, " \n", pro.strokeColor.c_str(), pro.strokeLineCap.c_str(),pro.lineWidthPt/100.0f); fprintf(fpo, " \n", meshIndex,pro.sizeCm[0],pro.sizeCm[1], pro.marginCm[0]+colInd*(pro.sizeCm[0]+pro.marginCm[0]), pro.marginCm[1]+rowInd*(pro.sizeCm[1]+pro.marginCm[1]) ); // Main loop of edge printing typename EdgeMeshType::EdgeIterator i; // XY projection. // It is a classcial ortho projection // eg it resolves to a rotation Matrix such that // - the passed projDir become the z axis // - the passed projUp lie on the upper YZ plane. // First Step align projDir to Z Matrix33f rotM = RotationMatrix(pro.projDir,Point3f(0,0,1),false); Point3f rotatedUp = rotM * pro.projUp; Point3f rotCenter = rotM * pro.projCenter; float scale = pro.scale; if(scale==0) scale = 2.0/mp.bbox.Diag(); for (i = mp.edge.begin(); i != mp.edge.end(); ++i) if(!(*i).IsD()) { Point3f p0 = (-rotCenter + rotM * ((*i).V(0)->P()))*scale*1000; Point3f p1 = (-rotCenter + rotM * ((*i).V(1)->P()))*scale*1000; fprintf(fpo, " \n", p0[0],p0[1],p1[0],p1[1]); } fprintf(fpo, " \n"); fprintf(fpo, "\n"); } }; }; // namespace io }; // namespace edge }; // namespace vcg #endif // __VCG_LIB_EXPORTER_SVG �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������meshlab-1.3.2+dfsg1/vcglib/wrap/gl/�����������������������������������������������������������������0000755�0001750�0001750�00000000000�12227522351�015700� 5����������������������������������������������������������������������������������������������������ustar �gladk���������������������������gladk������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������meshlab-1.3.2+dfsg1/vcglib/wrap/gl/camera.h���������������������������������������������������������0000644�0001750�0001750�00000100231�11517500604�017274� 0����������������������������������������������������������������������������������������������������ustar �gladk���������������������������gladk������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.14 2006/12/18 16:02:57 matteodelle minor eroor correction on variable names Revision 1.13 2006/12/18 14:28:07 matteodelle *** empty log message *** Revision 1.12 2006/12/18 09:46:39 callieri camera+shot revamp: changed field names to something with more sense, cleaning of various functions, correction of minor bugs/incongruences, removal of the infamous reference in shot. Revision 1.11 2006/01/10 12:22:34 spinelli add namespace vcg:: Revision 1.10 2005/10/24 14:42:57 spinelli add namespace vcg:: to GetFrustum(...) Revision 1.9 2005/06/29 15:02:29 spinelli aggiunto: - static void CavalieriProj( .. ) - static void IsometricProj( .. ) modificato: - static void TransformGL( .. ) - static void SetSubView( .. ) Revision 1.8 2005/02/22 10:57:05 tommyfranken corrected some syntax errors in GetFrustum Revision 1.7 2005/02/21 18:11:47 ganovelli GetFrustum moved from gl/camera to math/camera.h Revision 1.6 2004/12/16 14:41:36 ricciodimare *** empty log message *** Revision 1.5 2004/12/16 11:08:35 ricciodimare Cambiato il nome del costruttore era rimasto quello vecchio... e tolti alcune righe di codice commentate Revision 1.4 2004/12/15 18:45:06 tommyfranken *** empty log message *** Revision 1.3 2004/11/03 09:38:21 ganovelli added SetSubView, some comment and put the class back(!) Revision 1.2 2004/10/05 19:04:44 ganovelli changed from classes to functions Revision 1.1 2004/09/15 22:59:13 ganovelli creation ****************************************************************************/ #ifndef __GL_CAMERA #define __GL_CAMERA // VCG #include // opengl #include template struct GlCamera{ typedef typename CameraType::ScalarType ScalarType; typedef typename CameraType::ScalarType S; /// returns the OpenGL 4x4 PROJECTION matrix that describes the camera (intrinsics) static vcg::Matrix44 MatrixGL(vcg::Camera & cam, vcg::Matrix44 &m) { glPushAttrib(GL_TRANSFORM_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); TransformGL(cam); glGetv(GL_PROJECTION_MATRIX,&m[0][0]); glPopMatrix(); glPopAttrib(); return m; } /// set the OpenGL PROJECTION matrix for the Cavalieri projection static void SetGLCavalieriProj(float x1, float x2, float y1, float y2, float z1, float z2) { GLfloat cavalieri[16]; cavalieri[0] = 2.0f/(x2-x1); cavalieri[4] = 0; cavalieri[8] = (0.707106f * -2.0f)/(x2-x1); cavalieri[12] = (x2+x1)/(x2-x1); cavalieri[1] = 0; cavalieri[5] = 2.0/(y2-y1); cavalieri[9] = (0.707106f * -2.0f)/(y2-y1); cavalieri[13] = (y2+y1)/(y2-y1); cavalieri[2] = 0; cavalieri[6] = 0; cavalieri[10] = -2.0f/(z2-z1); cavalieri[14] = (z2+z1)/(z2-z1); cavalieri[3] = 0; cavalieri[7] = 0; cavalieri[11] = 0; cavalieri[15] = 1.0f; glLoadMatrixf(cavalieri); } /// set the OpenGL PROJECTION matrix for the Isometric projection static void SetGLIsometricProj(float x1, float x2, float y1, float y2, float z1, float z2) { GLfloat isometric[16]; isometric[0] = 1.6f/(x2-x1); isometric[4] = 0; isometric[8] = -1.6f/(x2-x1); isometric[12] = (x2+x1)/(x2-x1); isometric[1] = -1.0f/(y2-y1); isometric[5] = 2.0f/(y2-y1); isometric[9] = -1.0f/(y2-y1); isometric[13] = (y2+y1)/(y2-y1); isometric[2] = 0; isometric[6] = 0; isometric[10] = -2.0f/(z2-z1); isometric[14] = (z2+z1)/(z2-z1); isometric[3] = 0; isometric[7] = 0; isometric[11] = 0; isometric[15] = 1.0f; glLoadMatrixf(isometric); } /// get OpenGL-like frustum from a vcg camera (intrinsics) static void GetFrustum(vcg::Camera & intrinsics, S & sx,S & dx,S & bt,S & tp,S & f) { intrinsics.GetFrustum(sx,dx,bt,tp,f); } /// set the OpenGL PROJECTION matrix to match the camera (intrinsics). requires near and far plane static void TransformGL(vcg::Camera & camera, S nearDist, S farDist ) { S sx,dx,bt,tp,nr; camera.GetFrustum(sx,dx,bt,tp,nr); if(camera.cameraType == CameraType::PERSPECTIVE) { S ratio = nearDist/nr; sx *= ratio; dx *= ratio; bt *= ratio; tp *= ratio; } assert(glGetError()==0); switch(camera.cameraType) { case CameraType::PERSPECTIVE: glFrustum(sx,dx,bt,tp,nearDist,farDist); break; case CameraType::ORTHO: glOrtho(sx,dx,bt,tp,nearDist,farDist); break; case CameraType::ISOMETRIC: SetGLIsometricProj(sx,dx,bt,tp,nearDist,farDist); break; case CameraType::CAVALIERI: SetGLCavalieriProj(sx,dx,bt,tp,nearDist,farDist); break; } assert(glGetError()==0); }; static void GetViewSize(vcg::Camera & camera, S &width, S &height) { S sx,dx,bt,tp,nr,fr; GetFrustum(camera,sx,dx,bt,tp,nr,fr); width = dx-sx; //right - left = width height = tp-bt; //top - bottom = height }; static void SetSubView(vcg::Camera & camera,vcg::Point2 p0,S nearDist, S farDist,vcg::Point2 p1){ //typedef typename CameraType::ScalarType S; S sx,dx,bt,tp,f; GetFrustum(camera,sx,dx,bt,tp,f); S width = dx-sx; //right - left = width S height = tp-bt; //top - bottom = height /*glFrustum( width* p0[0]+ sx, width* p1[0]+ sx, height* p0[1]+ bt, height* p1[1]+ bt, nr,fr);*/ switch(camera.cameraType) { case CameraType::PERSPECTIVE: glFrustum( width* p0[0]+ sx, width* p1[0]+ sx, height* p0[1]+ bt, height* p1[1]+bt,nearDist,farDist); break; case CameraType::ORTHO: glOrtho(width* p0[0]+sx, width* p1[0]+sx, height* p0[1]+ bt, height* p1[1]+bt,nearDist,farDist); break; //case vcg::ISOMETRIC: IsometricProj(dx-width* p1[0], dx-width* p0[0], tp-height* p1[1], tp-height* p0[1],nearDist,farDist); break; //case vcg::CAVALIERI: CavalieriProj(dx-width* p1[0], dx-width* p0[0], tp-height* p1[1], tp-height* p0[1],nearDist,farDist); break; } assert(glGetError()==0); }; }; #endif //private: // // static inline S SQRT( S x) { return sqrt(fabs(x)); } // static inline S CBRT ( S x ) // { // if (x == 0) return 0; // else if (x > 0) return pow (x, 1.0 / 3.0); // else return -pow (-x, 1.0 / 3.0); // } // static inline void SINCOS( S x, S & s, S & c) // { // s=sin(x); // c=cos(x); // } // static inline void SINCOSd( double x, double & s, double & c) // { // s=sin(x); // c=cos(x); // } // static inline S CUB( S x ) { return x*x*x; } // static inline S SQR( S x ) { return x*x; } // //public: // void undistorted_to_distorted_sensor_coord (S Xu, S Yu, S & Xd, S & Yd) const // { // const S SQRT3 = S(1.732050807568877293527446341505872366943); // S Ru,Rd,lambda,c,d,Q,R,D,S,T,sinT,cosT; // // if((Xu==0 && Yu==0) || k[0] == 0) // { // Xd = Xu; // Yd = Yu; // return; // } // // Ru = hypot (Xu, Yu); /* SQRT(Xu*Xu+Yu*Yu) */ // c = 1 / k[0]; // d = -c * Ru; // // Q = c / 3; // R = -d / 2; // D = CUB (Q) + SQR (R); // // if (D >= 0) /* one real root */ // { // D = SQRT (D); // S = CBRT (R + D); // T = CBRT (R - D); // Rd = S + T; // // if (Rd < 0) // Rd = SQRT (-1 / (3 * k[0])); // } // else /* three real roots */ // { // D = SQRT (-D); // S = CBRT (hypot (R, D)); // T = atan2 (D, R) / 3; // SINCOS (T, sinT, cosT); // // /* the larger positive root is 2*S*cos(T) */ // /* the smaller positive root is -S*cos(T) + SQRT(3)*S*sin(T) */ // /* the negative root is -S*cos(T) - SQRT(3)*S*sin(T) */ // Rd = -S * cosT + SQRT3 * S * sinT; /* use the smaller positive root */ // } // // lambda = Rd / Ru; // // Xd = Xu * lambda; // Yd = Yu * lambda; // } // // //void correction(double k, float i, float j, float &disi, float &disj) //{ // // (i,j) punto nell'immagine distorta // // (disi,disj) punto nell'immagine corretta (undistorted) // float hyp; // float I,J,ni,nj; // float ratio = 1; // // ni = i-viewport[0]/2; // nj = j-viewport[1]/2; // hyp = ni*ni + nj*nj; // // I = ni * (1+ k * hyp); // J = nj * (1+ k * hyp); // // disi = (I*ratio+viewport[0]/2); // disj = (J*ratio+viewport[1]/2); //} // // // //void distorsion( float k ,float i, float j,double & disi, double &disj) //{ // // (i,j) punto nell'immagine corretta (undistorted) // // (disi,disj) punto nell'immagine distorta // float hyp; // int _I,_J; // float I,J,ni,nj; // I = i-viewport[0]/2; // J = j-viewport[1]/2; // hyp = sqrt(I*I + J*J); // if((k==0.0) || (hyp <0.001)) // { // disi = i; // disj = j; // } // else // { // undistorted_to_distorted_sensor_coord (I, J, disi, disj); // disi += viewport[0]/2; // disj += viewport[1]/2; // // //// hyp = (viewport[0]*viewport[0] + viewport[1]*viewport[1])/4; //// ni = SX/2 + SX/2 * cam.k[0] * hyp; ///// nj = SY/2 + SY/2 * cam.k[0] * hyp; //// float ratio = sqrt(hyp/(ni*ni + nj*nj)); // float ratio=1; // // // // //----------- Maple // // float t0,t1,t2,sol; // // //t0 = 1/k*pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/6.0-2.0/pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333); // // // //t1 = -1/k*pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/12.0+1/pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp* // //hyp*k)/k))*k*k,0.3333333333333333)+sqrt(-1.0)*sqrt(3.0)*(1/k*pow((108.0*hyp+ // //12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/6.0+2.0/ // //pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k, // //0.3333333333333333))/2.0; // // //t2 = -1/k*pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/12.0+1/pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp* // //hyp*k)/k))*k*k,0.3333333333333333)-sqrt(-1.0)*sqrt(3.0)*(1/k*pow((108.0*hyp+ // //12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k,0.3333333333333333)/6.0+2.0/ // //pow((108.0*hyp+12.0*sqrt(3.0)*sqrt((4.0+27.0*hyp*hyp*k)/k))*k*k, // //0.3333333333333333))/2.0; // // //sol = (t0>t1)?t0:t1; // //sol = (sol (i/(double)(si-1),j/(double)(sj-1)); // { // double disi,disj; // distorsion( k[0] ,(i/(double)(si-1))*viewport[0], (j/(double)(sj-1))*viewport[1],disi,disj); // gridMap[i][j] = Point2 (disi/viewport[0],disj/viewport[1]); // } // } // // inline Camera() // { // k[0]=k[1]=k[2]=k[3]=0.0; // valid = false; // ortho = false; // ResizeGridMap(100,100);// da spostare altrove // } // // inline bool IsValid() // { // return valid; // } // // inline bool IsOrtho() const // { // return ortho; // } // // inline void SetInvalid() // { // valid = false; // } // // inline void SetOrtho(bool isOrtho=true) // { // ortho = isOrtho; // } // // // Genera una camera standard // void Standard() // { // valid = true; // ortho = false; // view_p = vectorial(0,0,0); // x_axis = vectorial(1,0,0); // y_axis = vectorial(0,1,0); // z_axis = vectorial(0,0,1); // f = 25.75; // s = Point2(0.0074,0.0074); // c = Point2(320,240); // viewport[0] = 640; // viewport[1] = 480; // k[0] = 0; // k[1] = 0; // k[2] = 0; // k[3] = 0; // } // // // Trasla la camera (world coordinate) // inline void Translate( const vectorial & t ) // { // view_p += t; // } // // // Trasla la camera (camera coordinate) // inline void Move( const vectorial & t ) // { // view_p+= x_axis * t[0]+y_axis * t[1] + z_axis * t[2]; // } // // // scala la camera // inline void Scale(const scalar & sc){ // view_p *=sc; // s[0]*=sc; // s[1]*=sc; // f*=sc; // //printf("sc\n"); // } // // // // // NOTA funziona solo se l'ultima colonna di m e' 0,0,0,1 // void Apply( const Matrix44 & m ) // { // // Passo 1: calcolo pseudo inversa di m // S s11,s12,s13; // S s21,s22,s23; // S s31,s32,s33; // S s41,s42,s43; // // { // S t4 = m[0][0]*m[1][1]; // S t6 = m[0][0]*m[2][1]; // S t8 = m[1][0]*m[0][1]; // S t10 = m[1][0]*m[2][1]; // S t12 = m[2][0]*m[0][1]; // S t14 = m[2][0]*m[1][1]; // S t17 = 1/(t4*m[2][2]-t6*m[1][2]-t8*m[2][2]+t10*m[0][2]+t12*m[1][2]-t14*m[0][2]); // S t27 = m[1][0]*m[2][2]; // S t28 = m[2][0]*m[1][2]; // S t31 = m[0][0]*m[2][2]; // S t32 = m[2][0]*m[0][2]; // S t35 = m[0][0]*m[1][2]; // S t36 = m[1][0]*m[0][2]; // S t49 = m[3][0]*m[1][1]; // S t51 = m[3][0]*m[2][1]; // S t59 = m[3][0]*m[0][1]; // s11 = -(-m[1][1]*m[2][2]+m[2][1]*m[1][2])*t17; // s12 = -( m[0][1]*m[2][2]-m[2][1]*m[0][2])*t17; // s13 = ( m[0][1]*m[1][2]-m[1][1]*m[0][2])*t17; // s21 = (-t27+t28)*t17; // s22 = -(-t31+t32)*t17; // s23 = -( t35-t36)*t17; // s31 = -(-t10+t14)*t17; // s32 = (-t6 +t12)*t17; // s33 = ( t4 -t8 )*t17; // s41 = -(t10*m[3][2]-t27*m[3][1]-t14*m[3][2]+t28*m[3][1]+t49*m[2][2]-t51*m[1][2])*t17; // s42 = -(-t6*m[3][2]+t31*m[3][1]+t12*m[3][2]-t32*m[3][1]-t59*m[2][2]+t51*m[0][2])*t17; // s43 = (-t4*m[3][2]+t35*m[3][1]+t8 *m[3][2]-t36*m[3][1]-t59*m[1][2]+t49*m[0][2])*t17; // 1.0; // } // // //Matrix44 t2 = tt*m; // //print(t2); // // Fase 2: Calcolo nuovo punto di vista // { // S t1 = view_p[2]*s31; // S t3 = view_p[2]*s21; // S t5 = s43*s21; // S t7 = s43*s31; // S t9 = view_p[1]*s31; // S t11 = view_p[1]*s21; // S t13 = s42*s31; // S t15 = s42*s21; // S t17 = view_p[0]*s32; // S t19 = view_p[0]*s22; // S t21 = s41*s32; // S t23 = s41*s22; // S t25 = -t1*s22+t3*s32-t5*s32+t7*s22+t9*s23-t11*s33-t13*s23+t15*s33-t17*s23+t19*s33+t21*s23-t23*s33; // S t39 = 1/(s11*s22*s33-s11*s32*s23-s21*s12*s33+s21*s32*s13+s31*s12*s23-s31*s22*s13); // S t41 = view_p[0]*s12; // S t45 = s41*s12; // S t47 = view_p[2]*s11; // S t50 = s43*s11; // S t53 = view_p[1]*s11; // S t56 = s42*s11; // S t59 = t41*s33-t17*s13+t21*s13-t45*s33+t47*s32-t1*s12-t50*s32+t7*s12-t53*s33+t9*s13+t56*s33-t13*s13; // S t73 = t15*s13-t56*s23+t19*s13-t41*s23-t23*s13+t45*s23-t11*s13+t53*s23+t3*s12-t47*s22-t5*s12+t50*s22; // // view_p[0] = t25*t39; // view_p[1] = -t59*t39; // view_p[2] = -t73*t39; // } // // // Fase 3: Calcol nuovo sistema di riferimento // { // S A00 = s11*x_axis[0]+s12*x_axis[1]+s13*x_axis[2]; // S A01 = s11*y_axis[0]+s12*y_axis[1]+s13*y_axis[2]; // S A02 = s11*z_axis[0]+s12*z_axis[1]+s13*z_axis[2]; // // S A03 = 0.0; // S A10 = s21*x_axis[0]+s22*x_axis[1]+s23*x_axis[2]; // S A11 = s21*y_axis[0]+s22*y_axis[1]+s23*y_axis[2]; // S A12 = s21*z_axis[0]+s22*z_axis[1]+s23*z_axis[2]; // // S A13 = 0.0; // S A20 = s31*x_axis[0]+s32*x_axis[1]+s33*x_axis[2]; // S A21 = s31*y_axis[0]+s32*y_axis[1]+s33*y_axis[2]; // S A22 = s31*z_axis[0]+s32*z_axis[1]+s33*z_axis[2]; // // x_axis[0] = A00; x_axis[1] = A10; x_axis[2] = A20; // y_axis[0] = A01; y_axis[1] = A11; y_axis[2] = A21; // z_axis[0] = A02; z_axis[1] = A12; z_axis[2] = A22; // // S A1[2][3] = 0.0; // // S A1[3][0] = 0.0; // // S A1[3][1] = 0.0; // // S A1[3][2] = 0.0; // // S A1[3][3] = 1.0; // } // } // // /* // // Applica una trasformazione // void Apply( const Matrix44 & m ) // { // Point3 tx = view_p+x_axis; // Point3 ty = view_p+y_axis; // Point3 tz = view_p+z_axis; // // view_p = m.Apply(view_p); // // x_axis = m.Apply(tx) - view_p; // y_axis = m.Apply(ty) - view_p; // z_axis = m.Apply(tz) - view_p; // } // // // Applica una trasformazione ma bene! // void Stable_Apply( const Matrix44 & m ) // { // Point3 tx = view_p+x_axis; // Point3 ty = view_p+y_axis; // Point3 tz = view_p+z_axis; // // view_p = m.Stable_Apply(view_p); // // x_axis = m.Stable_Apply(tx) - view_p; // y_axis = m.Stable_Apply(ty) - view_p; // z_axis = m.Stable_Apply(tz) - view_p; // } // // */ // // void Project( const vectorial & p, Point2 & q ) const // { // vectorial dp = p - view_p; // S dx = dp*x_axis; // S dy = dp*y_axis; // S dz = dp*z_axis; // // S tx = dx; // S ty = -dy; // S qx,qy; // // // nota: per le camere ortogonali viewportM vale 1 // if(!IsOrtho()) // { // tx *= f/dz; // ty *= f/dz; // // undistorted_to_distorted_sensor_coord(tx,ty,qx,qy); // // q[0] = qx/s[0]+c[0]; // q[1] = qy/s[1]+c[1]; // } // else // { // q[0] = tx/(s[0]*viewportM)+c[0]; // q[1] = ty/(s[1]*viewportM)+c[1]; // } // } // //#if 1 // void Show( FILE * fp ) // { // if(valid) // fprintf(fp, // "posiz.: %g %g %g\n" // "x axis: %g %g %g\n" // "y axis: %g %g %g\n" // "z axis: %g %g %g\n" // "focal : %g scale: %g %g center: %g %g\n" // "viewp.: %d %d distorsion: %g %g %g %g\n" // ,view_p[0],view_p[1],view_p[2] // ,x_axis[0],x_axis[1],x_axis[2] // ,y_axis[0],y_axis[1],y_axis[2] // ,z_axis[0],z_axis[1],z_axis[2] // ,f,s[0],s[1],c[0],c[1] // ,viewport[0],viewport[1],k[0],k[1],k[2],k[3] // ); // else // fprintf(fp,"Invalid\n"); // } //#endif // // // Legge una camera in descrizione tsai binario // static void load_tsai_bin (FILE *fp, tsai_camera_parameters *cp, tsai_calibration_constants *cc) // { // double sa, // ca, // sb, // cb, // sg, // cg; // // fread(&(cp->Ncx),sizeof(double),1,fp); // fread(&(cp->Nfx),sizeof(double),1,fp); // fread(&(cp->dx),sizeof(double),1,fp); // fread(&(cp->dy),sizeof(double),1,fp); // fread(&(cp->dpx),sizeof(double),1,fp); // fread(&(cp->dpy),sizeof(double),1,fp); // fread(&(cp->Cx),sizeof(double),1,fp); // fread(&(cp->Cy),sizeof(double),1,fp); // fread(&(cp->sx),sizeof(double),1,fp); // // fread(&(cc->f),sizeof(double),1,fp); // fread(&(cc->kappa1),sizeof(double),1,fp); // fread(&(cc->Tx),sizeof(double),1,fp); // fread(&(cc->Ty),sizeof(double),1,fp); // fread(&(cc->Tz),sizeof(double),1,fp); // fread(&(cc->Rx),sizeof(double),1,fp); // fread(&(cc->Ry),sizeof(double),1,fp); // fread(&(cc->Rz),sizeof(double),1,fp); // // // SINCOSd (cc->Rx, sa, ca); // SINCOSd (cc->Ry, sb, cb); // SINCOSd (cc->Rz, sg, cg); // // cc->r1 = cb * cg; // cc->r2 = cg * sa * sb - ca * sg; // cc->r3 = sa * sg + ca * cg * sb; // cc->r4 = cb * sg; // cc->r5 = sa * sb * sg + ca * cg; // cc->r6 = ca * sb * sg - cg * sa; // cc->r7 = -sb; // cc->r8 = cb * sa; // cc->r9 = ca * cb; // // fread(&(cc->p1),sizeof(double),1,fp); // fread(&(cc->p2),sizeof(double),1,fp); // } // // void load_tsai (FILE *fp, tsai_camera_parameters *cp, tsai_calibration_constants *cc) // { // double sa, // ca, // sb, // cb, // sg, // cg; // // fscanf (fp, "%lf", &(cp->Ncx)); // fscanf (fp, "%lf", &(cp->Nfx)); // fscanf (fp, "%lf", &(cp->dx)); // fscanf (fp, "%lf", &(cp->dy)); // fscanf (fp, "%lf", &(cp->dpx)); // fscanf (fp, "%lf", &(cp->dpy)); // fscanf (fp, "%lf", &(cp->Cx)); // fscanf (fp, "%lf", &(cp->Cy)); // fscanf (fp, "%lf", &(cp->sx)); // // fscanf (fp, "%lf", &(cc->f)); // fscanf (fp, "%lf", &(cc->kappa1)); // fscanf (fp, "%lf", &(cc->Tx)); // fscanf (fp, "%lf", &(cc->Ty)); // fscanf (fp, "%lf", &(cc->Tz)); // fscanf (fp, "%lf", &(cc->Rx)); // fscanf (fp, "%lf", &(cc->Ry)); // fscanf (fp, "%lf", &(cc->Rz)); // // SINCOSd (cc->Rx, sa, ca); // SINCOSd (cc->Ry, sb, cb); // SINCOSd (cc->Rz, sg, cg); // // cc->r1 = cb * cg; // cc->r2 = cg * sa * sb - ca * sg; // cc->r3 = sa * sg + ca * cg * sb; // cc->r4 = cb * sg; // cc->r5 = sa * sb * sg + ca * cg; // cc->r6 = ca * sb * sg - cg * sa; // cc->r7 = -sb; // cc->r8 = cb * sa; // cc->r9 = ca * cb; // // fscanf (fp, "%lf", &(cc->p1)); // fscanf (fp, "%lf", &(cc->p2)); // } // // // Importa una camera dal formato tsai // void import( const tsai_camera_parameters & cp, // const tsai_calibration_constants & cc, // const int image_viewport[2] // ) // { // assert(!IsOrtho()); // valid = true; // x_axis[0] = cc.r1; x_axis[1] = cc.r2; x_axis[2] = cc.r3; // y_axis[0] = cc.r4; y_axis[1] = cc.r5; y_axis[2] = cc.r6; // z_axis[0] = cc.r7; z_axis[1] = cc.r8; z_axis[2] = cc.r9; // // view_p[0] = - (cc.Tx * x_axis[0] + cc.Ty * y_axis[0] + cc.Tz * z_axis[0]); // view_p[1] = - (cc.Tx * x_axis[1] + cc.Ty * y_axis[1] + cc.Tz * z_axis[1]); // view_p[2] = - (cc.Tx * x_axis[2] + cc.Ty * y_axis[2] + cc.Tz * z_axis[2]); // // s[0] = cp.dpx/cp.sx; // s[1] = cp.dpy; // c[0] = cp.Cx; // c[1] = cp.Cy; // // f = cc.f; // viewport[0] = image_viewport[0]; // viewport[1] = image_viewport[1]; // // k[0] = cc.kappa1; // k[1] = cc.kappa1; // k[2] = 0; // k[2] = 0; // } // // // Esporta una camera in formato tsai // void export( tsai_camera_parameters & cp, // tsai_calibration_constants & cc, // int image_viewport[2] // ) // { // assert(!IsOrtho()); // cc.r1 = x_axis[0]; cc.r2 = x_axis[1]; cc.r3= x_axis[2] ; // cc.r4 = y_axis[0]; cc.r5 = y_axis[1]; cc.r6= y_axis[2] ; // cc.r7 = z_axis[0]; cc.r8 = z_axis[1]; cc.r9= z_axis[2] ; // // cc.Tx = - (view_p[0] * x_axis[0] + view_p[1] * x_axis[1] + view_p[2] * x_axis[2]); // cc.Ty = - (view_p[0] * y_axis[0] + view_p[1] * y_axis[1] + view_p[2] * y_axis[2]); // cc.Tz = - (view_p[0] * z_axis[0] + view_p[1] * z_axis[1] + view_p[2] * z_axis[2]); // // cp.dpx = s[0]; // cp.dpy = s[1]; // // cp.Cx= c[0] ; // cp.Cy= c[1] ; // cp.sx= 1; // // cc.f= f ; // // image_viewport[0] = viewport[0]; // image_viewport[1] = viewport[1]; // // cc.kappa1= k[0] ; // cc.kappa1= k[1] ; // } // // // void Save(FILE * out) // { // fprintf(out,"VIEW_POINT %f %f %f\n", view_p[0],view_p[1],view_p[2]); // fprintf(out,"X_AXIS %f %f %f\n", x_axis[0],x_axis[1],x_axis[2]); // fprintf(out,"Y_AXIS %f %f %f\n", y_axis[0],y_axis[1],y_axis[2]); // fprintf(out,"Z_AXIS %f %f %f\n", z_axis[0],z_axis[1],z_axis[2]); // fprintf(out,"FOCUS_LENGHT %f \n", f); // fprintf(out,"SCALE %f %f \n", s[0], s[1]); // fprintf(out,"VIEWPORT %d %d \n", viewport[0], viewport[1]); // fprintf(out,"VIEWPORTM %f\n", viewportM); // fprintf(out,"RADIAL_DISTORSION %.10g %.10g \n", k[0],k[1]); // fprintf(out,"CENTER %f %f \n", c[0], c[1]); // fprintf(out,"IS_VALID %d\n", IsValid()); // fprintf(out,"END_CAMERA\n"); // } // // void Load(FILE * in) // { // char row[255]; // Standard(); // while(!feof(in)) // { // fscanf(in,"%s",row); // if(strcmp(row,"VIEW_POINT")==0) // fscanf(in,"%lg %lg %lg",&view_p[0],&view_p[1],&view_p[2]); // else // if(strcmp(row,"X_AXIS")==0) // fscanf(in,"%lg %lg %lg",& x_axis[0],&x_axis[1],&x_axis[2]); // else // if(strcmp(row,"Y_AXIS")==0) // fscanf(in,"%lg %lg %lg",& y_axis[0],&y_axis[1],&y_axis[2]); // else // if(strcmp(row,"Z_AXIS")==0) // fscanf(in,"%lg %lg %lg",& z_axis[0],&z_axis[1],&z_axis[2]); // else // if(strcmp(row,"FOCUS_LENGHT")==0) // fscanf(in,"%lg",&f); // else // if(strcmp(row,"SCALE")==0) // fscanf(in,"%lg %lg",&s[0],&s[1]); // else // if(strcmp(row,"VIEWPORT")==0) // fscanf(in,"%d %d", &viewport[0],&viewport[1]); // else // if(strcmp(row,"VIEWPORTM")==0) // fscanf(in,"%f", &viewportM); // else // if(strcmp(row,"CENTER")==0) // fscanf(in,"%lg %lg", &c[0],&c[1]); // else // if(strcmp(row,"RADIAL_DISTORSION")==0) // fscanf(in,"%lg %lg", &k[0],&k[1]); // else // if(strcmp(row,"IS_VALID")==0) // fscanf(in,"%d",&valid); // if(strcmp(row,"END_CAMERA")==0) // break; // } // } // //#ifdef __GL_H__ // //// Prende in ingresso il bounding box dell'oggetto da inquadrare e setta projection e modelmatrix //// in modo da matchare il piu' possibile quelle della camera. Ovviamente (?) si ignora le distorsioni radiali. //// Nota che bb viene utilizzato solo per settare i near e far plane in maniera sensata. //void SetGL(const Box3 &bb,scalar subx0=0, scalar subx1=1,scalar suby0=0,scalar suby1=1) //{ // scalar _,__; // SetGL(_,__,bb,subx0, subx1, suby0, suby1); // //} // //void SetGL(scalar &znear, scalar &zfar,const Box3 &bb,scalar subx0=0, // scalar subx1=1,scalar suby0=0,scalar suby1=1) //{ // glMatrixMode(GL_PROJECTION); // glLoadIdentity(); // scalar left,right; // scalar bottom, top; // scalar w,h; // // // La lunghezza focale e' la distanza del piano immagine dal centro di proiezione. // // il che mappa direttamente nella chiamata glFrustum che prende in ingresso // // le coordinate del piano immagine posto a znear. // // float imleft =-c[0]*s[0]; // float imright =(viewport[0]-c[0])*s[0]; // float imbottom =-c[1]*s[1]; // float imtop =(viewport[1]-c[1])*s[1]; // znear = Distance(view_p, bb.Center())-bb.Diag(); // zfar = Distance(view_p, bb.Center())+bb.Diag(); // // w=imright-imleft; // h=imtop-imbottom; // // // Quindi il frustum giusto sarebbe questo, // // glFrustum(imleft, imright, imbottom, imtop, f, zfar); // // ma per amor di opengl conviene spostare il near plane fino ad essere vicino all'oggetto da inquadrare. // // Cambiare f significa amplificare in maniera proporzionale anche i left right ecc. // // // 8/5/02 Nota che il near plane va spostato verso l'oggetto solo se quello calcolato sopra e' maggiore di 'f' // // nota che potrebbe anche succedere che znear <0 (viewpoint vicino ad un oggetto con il bb allungato); // if(znear c, scalar RadAngle) //{ // Point3 rnd(1.0 - 2.0*scalar(rand())/RAND_MAX, // 1.0 - 2.0*scalar(rand())/RAND_MAX, // 1.0 - 2.0*scalar(rand())/RAND_MAX); // rnd.Normalize(); // Matrix44 m,t0,t1,tr; // Point3 axis = rnd ^ (view_p-c).Normalize(); // scalar RadRandAngle=RadAngle*(1.0 - 2.0*scalar(rand())/RAND_MAX); // t0.Translate(c); // t1.Translate(-c); // m.Rotate(ToDeg(RadRandAngle),axis); // tr=t1*m*t0; // Apply(tr); //} // // // // //void glTexGen(int offx =0, // angolo basso sinistra della // int offy=0, // subtexture per la quale si vogliono settare le coordinate // int sx=1, // Dimensioni in Texel // int sy=1, // int Tx=1, // Dimensioni della texture // int Ty=1) //{ // // prendi la rototraslazione che // // trasforma la coordinata nel // // sistema di coordinate della camera // Matrix44d M; // M[0][0] = x_axis[0]; // M[0][1] = x_axis[1]; // M[0][2] = x_axis[2]; // M[0][3] = -view_p* x_axis ; // // M[1][0] = y_axis[0]; // M[1][1] = y_axis[1]; // M[1][2] = y_axis[2]; // M[1][3] = -view_p* y_axis; // // M[2][0] = z_axis[0]; // M[2][1] = z_axis[1]; // M[2][2] = z_axis[2]; // M[2][3] = -view_p* z_axis; // // M[3][0] = 0.0; // M[3][1] = 0.0; // M[3][2] = 0.0; // M[3][3] = 1.0; // // // prendi la matrice di proiezione // Matrix44d P; // P.SetZero(); // // if(!IsOrtho())// prospettica // { // // P[0][0] = sx/(s[0]*viewport[0]*Tx); // P[0][2] = (1/f)*(offx+0.5*sx)/Tx; // // P[1][1] = sy/(s[1]* viewport[1]*Ty); // P[1][2] = (1/f)*(offy+0.5*sy)/Ty; // // P[2][2] = 1; // P[3][2] = 1/f; // } // else // ortogonale // { // P[0][0] = sx/(s[0]*viewport[0]*viewportM*Tx); // P[0][3] = (offx+0.5*sx)/Tx; // l'effetto e' una traslazione di +1/2 // // P[1][1] = sy/(s[1]* viewport[1]*viewportM*Ty); // P[1][3] = (offy+0.5*sy)/Ty; // l'effetto e' una traslazione di +1/2 // // P[2][2] = 1; // P[3][3] = 1; // } // // componi // Matrix44d PM = P*M; // // glTexGend(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); // glTexGend(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); // glTexGend(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); // // glTexGendv(GL_S,GL_OBJECT_PLANE,&PM[0][0]); // glTexGendv(GL_T,GL_OBJECT_PLANE,&PM[1][0]); // glTexGendv(GL_Q,GL_OBJECT_PLANE,&PM[3][0]); // // glEnable(GL_TEXTURE_GEN_S); // glEnable(GL_TEXTURE_GEN_T); // glDisable(GL_TEXTURE_GEN_R); // glEnable(GL_TEXTURE_GEN_Q); //} // //// versione per le texture rettangolare NV_TEXTURE_RECTANGLE //// la differenza da glTexGen e' che il mapping e' in [0..sx]X[0..sy] //void glTexGen_NV(int sx, // Texture Size // int sy) //{ // // prendi la rototraslazione che // // trasforma la coordinata nel // // sistema di coordinate della camera // Matrix44d M; // M[0][0] = x_axis[0]; // M[0][1] = x_axis[1]; // M[0][2] = x_axis[2]; // M[0][3] = -view_p* x_axis ; // // M[1][0] = y_axis[0]; // M[1][1] = y_axis[1]; // M[1][2] = y_axis[2]; // M[1][3] = -view_p* y_axis; // // M[2][0] = z_axis[0]; // M[2][1] = z_axis[1]; // M[2][2] = z_axis[2]; // M[2][3] = -view_p* z_axis; // // M[3][0] = 0.0; // M[3][1] = 0.0; // M[3][2] = 0.0; // M[3][3] = 1.0; // // // prendi la matrice di proiezione // Matrix44d P; // P.SetZero(); // // if(!IsOrtho())// prospettica // { // // P[0][0] = sx/(s[0]*viewport[0]); // P[0][2] = sx*(1/f)*( 0.5); // // P[1][1] = sy/(s[1]* viewport[1] ); // P[1][2] = sy*(1/f)*( 0.5); // // P[2][2] = 1; // P[3][2] = 1/f; // } // else // ortogonale // { // P[0][0] = sx/(s[0]*viewport[0]*viewportM); // P[0][3] = sx* 0.5 ; // l'effetto e' una traslazione di +1/2 // // P[1][1] = sy/(s[1]* viewport[1]*viewportM); // P[1][3] = sy* 0.5 ; // l'effetto e' una traslazione di +1/2 // // P[2][2] = 1; // P[3][3] = 1; // } // // componi // Matrix44d PM = P*M; // // glTexGend(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); // glTexGend(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); // glTexGend(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); // // glTexGendv(GL_S,GL_OBJECT_PLANE,&PM[0][0]); // glTexGendv(GL_T,GL_OBJECT_PLANE,&PM[1][0]); // glTexGendv(GL_Q,GL_OBJECT_PLANE,&PM[3][0]); // // glEnable(GL_TEXTURE_GEN_S); // glEnable(GL_TEXTURE_GEN_T); // glDisable(GL_TEXTURE_GEN_R); // glEnable(GL_TEXTURE_GEN_Q); //// glDisable(GL_TEXTURE_GEN_Q); // //} //#endif // __GL_H__ // //}; //} // End namespace vcg meshlab-1.3.2+dfsg1/vcglib/wrap/gl/space.h0000644000175000017500000003173311517500604017151 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.10 2007/07/31 12:21:50 ganovelli added gltetra, added normal gltriangle Revision 1.9 2007/05/08 18:55:38 ganovelli glTriangle added Revision 1.8 2007/01/18 01:26:23 cignoni Added cast for mac compiling Revision 1.7 2005/10/13 08:32:26 cignoni Added glscale(scalar) and corrected bug in glscale(point2) Revision 1.6 2005/06/30 10:17:04 ganovelli added draw plane Revision 1.5 2005/05/05 12:28:13 cignoni added glboxwire Revision 1.4 2004/07/07 23:30:28 cignoni Added box3 drawing functions Revision 1.3 2004/05/26 15:13:01 cignoni Removed inclusion of gl extension stuff and added glcolor stuff Revision 1.2 2004/05/13 23:44:47 ponchio --> Revision 1.1 2004/04/05 11:56:14 cignoni First working version! ****************************************************************************/ #ifndef VCG_USE_EIGEN #include "deprecated_space.h" #else #ifndef VCG_GL_SPACE_H #define VCG_GL_SPACE_H // Please note that this file assume that you have already included your // gl-extension wrapping utility, and that therefore all the extension symbol are already defined. #include #include #include #include #include #include #include namespace vcg { template struct EvalToKnownPointType; template struct EvalToKnownPointType { typedef Point2 Type; }; template struct EvalToKnownPointType { typedef Point3 Type; }; template struct EvalToKnownPointType { typedef Point4 Type; }; #define _WRAP_EIGEN_XPR(FUNC) template \ inline void FUNC(const Eigen::MatrixBase& p) { \ FUNC(typename EvalToKnownPointType::Type(p)); } _WRAP_EIGEN_XPR(glVertex) _WRAP_EIGEN_XPR(glNormal) _WRAP_EIGEN_XPR(glTexCoord) _WRAP_EIGEN_XPR(glTranslate) _WRAP_EIGEN_XPR(glScale) inline void glScale(float const & p){ glScalef(p,p,p);} inline void glScale(double const & p){ glScaled(p,p,p);} template inline void glVertex(const Eigen::Matrix & p) { assert(0); } template<> inline void glVertex(const Eigen::Matrix & p) { glVertex2iv((const GLint*)p.data());} template<> inline void glVertex(const Eigen::Matrix & p) { glVertex2sv(p.data());} template<> inline void glVertex(const Eigen::Matrix & p) { glVertex2fv(p.data());} template<> inline void glVertex(const Eigen::Matrix & p){ glVertex2dv(p.data());} template inline void glTexCoord(const Eigen::Matrix & p) { assert(0); } template<> inline void glTexCoord(const Eigen::Matrix & p) { glTexCoord2iv((const GLint*)p.data());} template<> inline void glTexCoord(const Eigen::Matrix & p) { glTexCoord2sv(p.data());} template<> inline void glTexCoord(const Eigen::Matrix & p) { glTexCoord2fv(p.data());} template<> inline void glTexCoord(const Eigen::Matrix & p){ glTexCoord2dv(p.data());} template inline void glTranslate(const Eigen::Matrix & p) { assert(0); } template<> inline void glTranslate(const Eigen::Matrix & p) { glTranslatef(p[0],p[1],0);} template<> inline void glTranslate(const Eigen::Matrix & p){ glTranslated(p[0],p[1],0);} template inline void glScale(const Eigen::Matrix & p) { assert(0); } template<> inline void glScale(const Eigen::Matrix & p) { glScalef(p[0],p[1],1.f);} template<> inline void glScale(const Eigen::Matrix & p){ glScaled(p[0],p[1],1.0);} template inline void glVertex(const Eigen::Matrix & p) { assert(0); } template<> inline void glVertex(const Eigen::Matrix & p) { glVertex3iv((const GLint*)p.data());} template<> inline void glVertex(const Eigen::Matrix & p) { glVertex3sv(p.data());} template<> inline void glVertex(const Eigen::Matrix & p) { glVertex3fv(p.data());} template<> inline void glVertex(const Eigen::Matrix & p){ glVertex3dv(p.data());} template inline void glNormal(const Eigen::Matrix & p) { assert(0); } template<> inline void glNormal(const Eigen::Matrix & p) { glNormal3iv((const GLint*)p.data());} template<> inline void glNormal(const Eigen::Matrix & p) { glNormal3sv(p.data());} template<> inline void glNormal(const Eigen::Matrix & p) { glNormal3fv(p.data());} template<> inline void glNormal(const Eigen::Matrix & p){ glNormal3dv(p.data());} template inline void glTexCoord(const Eigen::Matrix & p) { assert(0); } template<> inline void glTexCoord(const Eigen::Matrix & p) { glTexCoord3iv((const GLint*)p.data());} template<> inline void glTexCoord(const Eigen::Matrix & p) { glTexCoord3sv(p.data());} template<> inline void glTexCoord(const Eigen::Matrix & p) { glTexCoord3fv(p.data());} template<> inline void glTexCoord(const Eigen::Matrix & p){ glTexCoord3dv(p.data());} template inline void glTranslate(const Eigen::Matrix & p) { assert(0); } template<> inline void glTranslate(const Eigen::Matrix & p) { glTranslatef(p[0],p[1],p[2]);} template<> inline void glTranslate(const Eigen::Matrix & p){ glTranslated(p[0],p[1],p[2]);} template inline void glScale(const Eigen::Matrix & p) { assert(0); } template<> inline void glScale(const Eigen::Matrix & p) { glScalef(p[0],p[1],p[2]);} template<> inline void glScale(const Eigen::Matrix & p){ glScaled(p[0],p[1],p[2]);} inline void glColor(Color4b const & c) { glColor4ubv(c.data());} inline void glClearColor(Color4b const &c) { ::glClearColor(float(c[0])/255.0f,float(c[1])/255.0f,float(c[2])/255.0f,1.0f);} inline void glLight(GLenum light, GLenum pname, Color4b const & c) { static float cf[4]; cf[0]=float(cf[0]/255.0); cf[1]=float(c[1]/255.0); cf[2]=float(c[2]/255.0); cf[3]=float(c[3]/255.0); glLightfv(light,pname,cf); } template inline void glBoxWire(Box3 const & b) { glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glBegin(GL_LINE_STRIP); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.min[2]); glVertex3f((float)b.max[0],(float)b.min[1],(float)b.min[2]); glVertex3f((float)b.max[0],(float)b.max[1],(float)b.min[2]); glVertex3f((float)b.min[0],(float)b.max[1],(float)b.min[2]); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.min[2]); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.max[2]); glVertex3f((float)b.max[0],(float)b.min[1],(float)b.max[2]); glVertex3f((float)b.max[0],(float)b.max[1],(float)b.max[2]); glVertex3f((float)b.min[0],(float)b.max[1],(float)b.max[2]); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.max[2]); glEnd(); glBegin(GL_LINES); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.min[2]); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.max[2]); glVertex3f((float)b.max[0],(float)b.min[1],(float)b.min[2]); glVertex3f((float)b.max[0],(float)b.min[1],(float)b.max[2]); glVertex3f((float)b.max[0],(float)b.max[1],(float)b.min[2]); glVertex3f((float)b.max[0],(float)b.max[1],(float)b.max[2]); glVertex3f((float)b.min[0],(float)b.max[1],(float)b.min[2]); glVertex3f((float)b.min[0],(float)b.max[1],(float)b.max[2]); glEnd(); glPopAttrib(); }; template /// Funzione di utilita' per la visualizzazione in OpenGL (flat shaded) inline void glBoxFlat(Box3 const & b) { glPushAttrib(GL_SHADE_MODEL); glShadeModel(GL_FLAT); glBegin(GL_QUAD_STRIP); glNormal3f(.0f,.0f,1.0f); glVertex3f(b.min[0], b.max[1], b.max[2]); glVertex3f(b.min[0], b.min[1], b.max[2]); glVertex3f(b.max[0], b.max[1], b.max[2]); glVertex3f(b.max[0], b.min[1], b.max[2]); glNormal3f(1.0f,.0f,.0f); glVertex3f(b.max[0], b.max[1], b.min[2]); glVertex3f(b.max[0], b.min[1], b.min[2]); glNormal3f(.0f,.0f,-1.0f); glVertex3f(b.min[0], b.max[1], b.min[2]); glVertex3f(b.min[0], b.min[1], b.min[2]); glNormal3f(-1.0f,.0f,.0f); glVertex3f(b.min[0], b.max[1], b.max[2]); glVertex3f(b.min[0], b.min[1], b.max[2]); glEnd(); glBegin(GL_QUADS); glNormal3f(.0f,1.0f,.0f); glVertex3f(b.min[0], b.max[1], b.max[2]); glVertex3f(b.max[0], b.max[1], b.max[2]); glVertex3f(b.max[0], b.max[1], b.min[2]); glVertex3f(b.min[0], b.max[1], b.min[2]); glNormal3f(.0f,-1.0f,.0f); glVertex3f(b.min[0], b.min[1], b.min[2]); glVertex3f(b.max[0], b.min[1], b.min[2]); glVertex3f(b.max[0], b.min[1], b.max[2]); glVertex3f(b.min[0], b.min[1], b.max[2]); glEnd(); glPopAttrib(); }; template /// Setta i sei clip planes di opengl a far vedere solo l'interno del box inline void glBoxClip(const Box3 & b) { double eq[4]; eq[0]= 1; eq[1]= 0; eq[2]= 0; eq[3]=(double)-b.min[0]; glClipPlane(GL_CLIP_PLANE0,eq); eq[0]=-1; eq[1]= 0; eq[2]= 0; eq[3]=(double) b.max[0]; glClipPlane(GL_CLIP_PLANE1,eq); eq[0]= 0; eq[1]= 1; eq[2]= 0; eq[3]=(double)-b.min[1]; glClipPlane(GL_CLIP_PLANE2,eq); eq[0]= 0; eq[1]=-1; eq[2]= 0; eq[3]=(double) b.max[1]; glClipPlane(GL_CLIP_PLANE3,eq); eq[0]= 0; eq[1]= 0; eq[2]= 1; eq[3]=(double)-b.min[2]; glClipPlane(GL_CLIP_PLANE4,eq); eq[0]= 0; eq[1]= 0; eq[2]=-1; eq[3]=(double) b.max[2]; glClipPlane(GL_CLIP_PLANE5,eq); } template inline void glBoxWire(const Box2 & b) { glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glBegin(GL_LINE_LOOP); glVertex2f((float)b.min[0],(float)b.min[1]); glVertex2f((float)b.max[0],(float)b.min[1]); glVertex2f((float)b.max[0],(float)b.max[1]); glVertex2f((float)b.min[0],(float)b.max[1]); glEnd(); glPopAttrib(); }; template inline void glPlane3( Plane3 p, Point3 c, T size ) { Point3 w = p.Direction(); Point3 u,v,c1; GetUV(w,u,v); c1 = p.Projection(c); u.Normalize(); w.Normalize(); v.Normalize(); Matrix44 m; *(Point3*)&m[0][0] = *(Point3*)&u[0];m[0][3]=0; *(Point3*)&m[1][0] = *(Point3*)&w[0];m[1][3]=0; *(Point3*)&m[2][0] = *(Point3*)&v[0];m[2][3]=0; *(Point3*)&m[3][0] = *(Point3*)&c1[0];m[3][3]=1; glPushMatrix(); glMultMatrix(m.transpose()); glBegin(GL_QUADS); glNormal(Point3(0,1,0)); glVertex(Point3(-size,0,-size)); glVertex(Point3(size ,0,-size)); glVertex(Point3(size ,0, size)); glVertex(Point3(-size,0, size)); glEnd(); glPopMatrix(); } template inline void glTriangle3( TriangleType & c ) { vcg::Point3 n = vcg::Normal(c); glBegin(GL_TRIANGLES); glNormal(n); glVertex(c.P(0)); glVertex(c.P(1)); glVertex(c.P(2)); glEnd(); } template inline void glTetra3( TetraType & c ) { glTriangle3(Triangle3(c.P(0),c.P(1),c.P(2))); glTriangle3(Triangle3(c.P(1),c.P(3),c.P(2))); glTriangle3(Triangle3(c.P(0),c.P(2),c.P(3))); glTriangle3(Triangle3(c.P(1),c.P(0),c.P(3))); } }//namespace #endif #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/gl_object.h0000644000175000017500000000467211517500604020010 0ustar gladkgladk/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef __GL_OBJECT_H__ #define __GL_OBJECT_H__ class GLObject { public: GLObject(void) { this->objectID = 0; } virtual ~GLObject(void) { } GLuint ObjectID(void) const { return this->objectID; } bool ValidObject(void) const { return (this->objectID != 0); } virtual void Gen(void) = 0; virtual void Del(void) = 0; protected: GLuint objectID; }; class Bindable { public: Bindable(void) { this->bound = false; } void Bind(void) { this->bound = true; this->DoBind(); } void Unbind(void) { this->DoUnbind(); this->bound = false; } bool IsBound(void) const { return this->bound; } protected: bool bound; virtual void DoBind(void) = 0; virtual void DoUnbind(void) = 0; }; #endif //__GL_OBJECT_H__ meshlab-1.3.2+dfsg1/vcglib/wrap/gl/glu_tessellator_cap.h0000644000175000017500000000434411732414760022115 0ustar gladkgladk#ifndef GLU_TESSELLATOR_CAP_H #define GLU_TESSELLATOR_CAP_H #include "glu_tesselator.h" #include #include #include namespace vcg { namespace tri { // This function take a mesh with one or more boundary stored as edges, and fill another mesh with a triangulation of that boundaries. // it assumes that boundary are planar and exploits glutessellator for the triangulaiton template void CapEdgeMesh(MeshType &em, MeshType &cm, bool revertFlag=false) { typedef typename MeshType::EdgeType EdgeType; std::vector< std::vector > outlines; std::vector outline; UpdateFlags::EdgeClearV(em); UpdateTopology::EdgeEdge(em); int nv=0; for(size_t i=0;i startE(&em.edge[i],0); edge::Pos curE=startE; do { curE.E()->SetV(); outline.push_back(curE.V()->P()); curE.NextE(); nv++; } while(curE != startE); if(revertFlag) std::reverse(outline.begin(),outline.end()); outlines.push_back(outline); outline.clear(); } } if (nv<2) return; // printf("Found %i outlines for a total of %i vertices",outlines.size(),nv); typename MeshType::VertexIterator vi=vcg::tri::Allocator::AddVertices(cm,nv); for (size_t i=0;iP()=outlines[i][j]; } std::vector indices; glu_tesselator::tesselate(outlines, indices); std::vector points; glu_tesselator::unroll(outlines, points); //typename MeshType::FaceIterator fi=tri::Allocator::AddFaces(cm,nv-2); typename MeshType::FaceIterator fi=tri::Allocator::AddFaces(cm,indices.size()/3); for (size_t i=0; iV(0)=&cm.vert[ indices[i+0] ]; (*&fi)->V(1)=&cm.vert[ indices[i+1] ]; (*&fi)->V(2)=&cm.vert[ indices[i+2] ]; } Clean::RemoveDuplicateVertex(cm); UpdateBounding::Box(cm); } } // end namespace tri } // end namespace vcg #endif // GLU_TESSELLATOR_CAP_H meshlab-1.3.2+dfsg1/vcglib/wrap/gl/shaders.h0000644000175000017500000003027611732414760017516 0ustar gladkgladk/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef __SHADERS_H__ #define __SHADERS_H__ #include #include #include #include "gl_object.h" #include "../../vcg/space/point2.h" #include "../../vcg/space/point3.h" #include "../../vcg/space/point4.h" class Shader : public GLObject, public Bindable { public: typedef enum { VERTEX, FRAGMENT, GEOMETRY } ShaderType; Shader(void) : GLObject(), Bindable() { this->flags = 0; this->flags |= SOURCE_DIRTY; this->compiled = false; } void Gen(void) { this->Del(); GLenum t; switch (this->Type()) { case Shader::VERTEX : t = GL_VERTEX_SHADER; break; case Shader::FRAGMENT : t = GL_FRAGMENT_SHADER; break; case Shader::GEOMETRY : t = GL_GEOMETRY_SHADER_EXT; break; default: return; }; this->objectID = glCreateShader(t); } void Del(void) { if (this->objectID == 0) return; glDeleteShader(this->objectID); this->objectID = 0; } virtual ShaderType Type(void) const = 0; void SetSource(const char * src) { if (this->objectID==0) Gen(); this->flags |= SOURCE_DIRTY; this->compiled = false; this->source = src; const char * pSrc = this->source.c_str(); glShaderSource(this->objectID, 1, &pSrc, 0); } bool LoadSource(const char * fileName) { if (this->objectID==0) Gen(); this->flags |= SOURCE_DIRTY; this->compiled = false; FILE * f = fopen(fileName, "rb"); if (f == 0) { this->source = ""; return false; } fseek(f, 0, SEEK_END); const size_t sz = (size_t)ftell(f); rewind(f); char * buff = new char[sz + 1]; fread(buff, sizeof(char), sz, f); fclose(f); buff[sz] = '\0'; this->source = buff; delete [] buff; const char * pSrc = this->source.c_str(); glShaderSource(this->objectID, 1, &pSrc, 0); return true; } bool Compile(void) { glCompileShader(this->objectID); GLint cm = 0; glGetShaderiv(this->objectID, GL_COMPILE_STATUS, &cm); this->compiled = (cm != GL_FALSE); this->flags = 0; return this->compiled; } bool IsCompiled(void) { return this->compiled; } std::string InfoLog(void) { GLint len = 0; glGetShaderiv(this->objectID, GL_INFO_LOG_LENGTH, &len); char * ch = new char[len + 1]; glGetShaderInfoLog(this->objectID, len, &len, ch); std::string infoLog = ch; delete [] ch; return infoLog; } protected: enum { SOURCE_DIRTY }; std::string source; unsigned int flags; bool compiled; void DoBind(void) { } void DoUnbind(void) { } }; class VertexShader : public Shader { public: VertexShader(void) : Shader() { } ShaderType Type(void) const { return Shader::VERTEX; } }; class FragmentShader : public Shader { public: FragmentShader(void) : Shader() { } ShaderType Type(void) const { return Shader::FRAGMENT; } }; class GeometryShader : public Shader { public: GeometryShader(void) : Shader() { } ShaderType Type(void) const { return Shader::GEOMETRY; } }; #if 0 class Program; class Uniform { friend class Program; public: /* typedef enum { U_BOOL, U_BVEC2, U_BVEC3, U_BVEC4, U_BMAT2, U_BMAT3, U_BMAT4, U_INT, U_IVEC2, U_IVEC3, U_IVEC4, U_IMAT2, U_IMAT3, U_IMAT4, U_FLOAT, U_FVEC2, U_FVEC3, U_FVEC4, U_FMAT2, U_FMAT3, U_FMAT4, U_SAMPLER1D, U_SAMPLER2D, U_SAMPLER3D, U_SAMPLERCUBE, U_SAMPLER1DSHADOW, U_SAMPLER2DSHADOW } UniformType; */ const std::string & Name(void) const { return this->name; } virtual GLenum Type(void) const = 0; protected: Program * prog; GLint location; std::string name; Uniform(Program * prog, GLint location, const std::string & name) { this->prog = prog; this->location = location; this->name = name; } virtual void Apply(void) = 0; }; class Uniform1b : public Uniform; { public: void SetValue(GLboolean x) { this->value[0] = x; } GLboolean GetValue(void) const { return this->value[0]; } protected: Program * prog; GLboolean value[1]; Uniform(Program * prog, GLint location, const std::string & name) : Uniform(prog, location, name) { this->value = GL_FALSE; } }; class Uniform2b : public Uniform; { public: void SetValue(GLboolean x, GLboolean y) { this->value[0] = x; this->value[1] = y; } GLboolean GetValueX(void) const { return this->value[0]; } GLboolean GetValueY(void) const { return this->value[1]; } protected: Program * prog; GLboolean value[2]; Uniform(Program * prog, GLint location, const std::string & name) : Uniform(prog, location, name) { this->value[0] = GL_FALSE; this->value[1] = GL_FALSE; } }; class Uniform3b : public Uniform; { public: void SetValue(GLboolean x, GLboolean y, GLboolean z) { this->value[0] = x; this->value[1] = y; this->value[2] = z; } GLboolean GetValueX(void) const { return this->value[0]; } GLboolean GetValueY(void) const { return this->value[1]; } GLboolean GetValueZ(void) const { return this->value[2]; } protected: Program * prog; GLboolean value[2]; Uniform(Program * prog, GLint location, const std::string & name) : Uniform(prog, location, name) { this->value[0] = GL_FALSE; this->value[1] = GL_FALSE; } }; class Uniform1i : public Uniform; { public: void SetValue(GLint v) { this->value = v; } GLint GetValue(void) const { return this->value; } protected: Program * prog; GLint value; Uniform(Program * prog, GLint location, const std::string & name) : Uniform(prog, location, name) { this->value = 0; } }; #endif class Program : public GLObject, public Bindable { public: Program(void) { this->linked = false; } void Gen(void) { this->Del(); this->objectID = glCreateProgram(); } void Del(void) { if (this->objectID == 0) return; glDeleteProgram(this->objectID); this->objectID = 0; } void Attach(Shader * shd) { if (this->objectID==0) Gen(); this->shaders.insert(shd); this->linked = false; glAttachShader(this->objectID, shd->ObjectID()); } void Detach(Shader * shd) { this->shaders.erase(shd); this->linked = false; glDetachShader(this->objectID, shd->ObjectID()); } GLsizei AttachedShaders(void) const { return ((GLsizei)(this->shaders.size())); } Shader * AttachedShader(int i) { Shader * shd = 0; int cnt = 0; for (std::set::iterator it=this->shaders.begin(); (cnt < i) && (it!=this->shaders.end()); ++it) { shd = (*it); } return shd; } bool Link(void) { bool ok = true; for (std::set::iterator it=this->shaders.begin(); it!=this->shaders.end(); ++it) { Shader * shd = (*it); if (!shd->IsCompiled()) { ok = shd->Compile() && ok; } } if (!ok) return false; glLinkProgram(this->objectID); GLint cm = 0; glGetProgramiv(this->objectID, GL_LINK_STATUS, &cm); this->linked = (cm != GL_FALSE); return this->linked; } bool IsLinked(void) const { return this->linked; } std::string InfoLog(void) { GLint len = 0; glGetProgramiv(this->objectID, GL_INFO_LOG_LENGTH, &len); char * ch = new char[len + 1]; glGetProgramInfoLog(this->objectID, len, &len, ch); std::string infoLog = ch; delete [] ch; return infoLog; } void Uniform(const char * name, GLint x) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform1i(loc, x); } void Uniform(const char * name, GLint x, GLint y) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform2i(loc, x, y); } void Uniform(const char * name, GLint x, GLint y, GLint z) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform3i(loc, x, y, z); } void Uniform(const char * name, GLint x, GLint y, GLint z, GLint w) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform4i(loc, x, y, z, w); } void Uniform(const char * name, GLfloat x) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform1f(loc, x); } void Uniform(const char * name, GLfloat x, GLfloat y) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform2f(loc, x, y); } void Uniform(const char * name, GLfloat x, GLfloat y, GLfloat z) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform3f(loc, x, y, z); } void Uniform(const char * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform4f(loc, x, y, z, w); } void Uniform(const char * name, const vcg::Point2f& p) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform2fv(loc, 1, p.V()); } void Uniform(const char * name, const vcg::Point3f& p) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform3fv(loc, 1, p.V()); } void Uniform(const char * name, const vcg::Point4f& p) { const GLint loc = glGetUniformLocation(this->objectID, name); glUniform4fv(loc, 1, p.V()); } void Parameter(GLenum pname, int value) { glProgramParameteriEXT(this->objectID, pname, value); } void Attribute(int index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { glVertexAttrib4f(index, x, y, z, w); } void BindAttribute(int index, const char * name) { glBindAttribLocation(this->objectID, index, name); } protected: std::set shaders; bool linked; void DoBind(void) { if (!this->IsLinked()) { this->Link(); } glUseProgram(this->objectID); } void DoUnbind(void) { glUseProgram(0); } }; class ProgramVF : public Bindable { public: Program prog; VertexShader vshd; FragmentShader fshd; ProgramVF(void) : Bindable() { } void SetSources(const char * vsrc, const char * fsrc) { if (vsrc) { this->vshd.SetSource(vsrc); this->prog.Attach(&(this->vshd)); } if (fsrc) { this->fshd.SetSource(fsrc); this->prog.Attach(&(this->fshd)); } } void LoadSources(const char * vfile, const char * ffile) { if (vfile) { this->vshd.LoadSource(vfile); this->prog.Attach(&(this->vshd)); } if (ffile) { this->fshd.LoadSource(ffile); this->prog.Attach(&(this->fshd)); } } protected: void DoBind(void) { this->prog.Bind(); } void DoUnbind(void) { this->prog.Unbind(); } }; #endif // __SHADERS_H__ meshlab-1.3.2+dfsg1/vcglib/wrap/gl/gl_geometry.h0000644000175000017500000001171411517500604020370 0ustar gladkgladk#ifndef _VCG_GL_GEOMETRY_ #define _VCG_GL_GEOMETRY_ /* Portion of this file were more or less adapted from * freeglut_geometry.c * * Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved. * that was Written by Pawel W. Olszta, */ #include #include /* * Compute lookup table of cos and sin values forming a cirle * * Notes: * It is the responsibility of the caller to free these tables * The size of the table is (n+1) to form a connected loop * The last entry is exactly the same as the first * The sign of n can be flipped to get the reverse loop */ static void fghCircleTable(double **sint,double **cost,const int n) { int i; /* Table size, the sign of n flips the circle direction */ const int size = abs(n); /* Determine the angle between samples */ const double angle = 2*M_PI/(double)( ( n == 0 ) ? 1 : n ); /* Allocate memory for n samples, plus duplicate of first entry at the end */ *sint = (double *) calloc(sizeof(double), size+1); *cost = (double *) calloc(sizeof(double), size+1); /* Bail out if memory allocation fails, fgError never returns */ if (!(*sint) || !(*cost)) { free(*sint); free(*cost); abort(); //fgError("Failed to allocate memory in fghCircleTable"); } /* Compute cos and sin around the circle */ (*sint)[0] = 0.0; (*cost)[0] = 1.0; for (i=1; i0)?1:0]; r0 = 0.0; r1 = sint2[(stacks>0)?1:0]; glBegin(GL_TRIANGLE_FAN); glNormal3d(0,0,1); glVertex3d(0,0,radius); for (j=slices; j>=0; j--) { glNormal3d(cost1[j]*r1, sint1[j]*r1, z1 ); glVertex3d(cost1[j]*r1*radius, sint1[j]*r1*radius, z1*radius); } glEnd(); /* Cover each stack with a quad strip, except the top and bottom stacks */ for( i=1; i class GLField { typedef typename MeshType::FaceType FaceType; typedef typename MeshType::VertexType VertexType; typedef typename MeshType::ScalarType ScalarType; static void GLDrawField(CoordType dir[4], CoordType center, ScalarType &size) { glLineWidth(1); vcg::Color4b c; vcg::glColor(vcg::Color4b(0,0,0,255)); glBegin(GL_LINES); for (int i=0;i<4;i++) { glVertex(center); glVertex(center+dir[i]*size); } glEnd(); } ///draw the cross field of a given face static void GLDrawFaceField(const MeshType &mesh, const FaceType &f, ScalarType &size) { CoordType center=(f.P0(0)+f.P0(1)+f.P0(2))/3; CoordType normal=f.cN(); CoordType dir[4]; vcg::tri::CrossField::CrossVector(f,dir); GLDrawField(dir,center,size); } static void GLDrawVertField(const MeshType &mesh, const VertexType &v, ScalarType &size) { CoordType center=v.cP(); CoordType normal=v.cN(); CoordType dir[4]; vcg::tri::CrossField::CrossVector(v,dir); GLDrawField(dir,center,size); } public: ///singular vertices should be selected static void GLDrawSingularities(const MeshType &mesh) { glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); glDepthRange(0,0.999); MyScalarType size=10; glPointSize(size); glBegin(GL_POINTS); for (int i=0;i::IsSingular(mesh.vert[i],mmatch); if (!IsSing)continue; assert(IsSing); assert(mmatch!=0); /*vcg::glColor(vcg::Color4b(255,0,0,255));*/ if (mmatch==1)vcg::glColor(vcg::Color4b(0,0,255,255)); else if (mmatch==2)vcg::glColor(vcg::Color4b(255,0,0,255)); else if (mmatch==3)vcg::glColor(vcg::Color4b(0,255,255,255)); vcg::glVertex(mesh.vert[i].P()); } glEnd(); glPopAttrib(); } static void GLDrawFaceField(const MeshType &mesh) { glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); MyScalarType size=mesh.bbox.Diag()/100.0; vcg::Color4b c=vcg::Color4b(255,0,0,255); for (int i=0;i -> Revision 1.8 2004/09/28 14:04:36 ganovelli glGet added Revision 1.7 2004/07/13 15:55:57 cignoni Added test on presence of glTranspose extension (for old hw support) Revision 1.6 2004/05/26 15:12:39 cignoni Removed inclusion of gl extension stuff Revision 1.5 2004/05/12 20:54:55 ponchio *** empty log message *** Revision 1.4 2004/05/12 13:07:47 ponchio Added #include Revision 1.3 2004/05/04 23:36:23 cignoni remove include of gl and added glextgension exploiting, Revision 1.2 2004/04/07 10:47:03 cignoni inlined functions for avoid multiple linking errors Revision 1.1 2004/03/31 15:27:17 ponchio *** empty log message *** ****************************************************************************/ #ifndef VCG_USE_EIGEN #include "deprecated_math.h" #else #ifndef VCG_GL_MATH_H #define VCG_GL_MATH_H // Please note that this file assume that you have already included your // gl-extension wrapping utility, and that therefore all the extension symbol are already defined. #include #include //#include // please do not include it! namespace vcg { template inline void glLoadMatrix(const Eigen::Matrix& matrix) { assert(0); } template<> inline void glLoadMatrix(const Eigen::Matrix& matrix) { glLoadMatrixf(matrix.data()); } template<> inline void glLoadMatrix(const Eigen::Matrix& matrix) { Eigen::Matrix4f tmp(matrix); glLoadMatrixf(tmp.data()); } inline void glLoadMatrix(const Eigen::Matrix& matrix) { glLoadMatrixd(matrix.data()); } inline void glLoadMatrix(const Eigen::Matrix& matrix) { Eigen::Matrix4d tmp(matrix); glLoadMatrixd(tmp.data()); } template inline void glLoadMatrix(const Eigen::Transform& t) { glLoadMatrix(t.matrix()); } template inline void glMultMatrix(const Eigen::Matrix& matrix) { assert(0); } template<> inline void glMultMatrix(const Eigen::Matrix& matrix) { glMultMatrixf(matrix.data()); } inline void glMultMatrix(const Eigen::Matrix& matrix) { Eigen::Matrix tmp(matrix); glMultMatrixf(tmp.data()); } template<> inline void glMultMatrix(const Eigen::Matrix& matrix) { glMultMatrixd(matrix.data()); } template<> inline void glMultMatrix(const Eigen::Matrix& matrix) { Eigen::Matrix tmp(matrix); glMultMatrixd(tmp.data()); } template inline void glMultMatrix(const Eigen::Transform& t) { glMultMatrix(t.matrix()); } inline void glMultMatrix(const Similarityf &s) { glTranslatef(s.tra[0], s.tra[1], s.tra[2]); glScalef(s.sca, s.sca, s.sca); float alpha; Point3f axis; s.rot.ToAxis(alpha, axis); glRotatef(math::ToDeg(alpha), axis[0], axis[1], axis[2]); } inline void glMultMatrix(const Similarityd &s) { glTranslated(s.tra[0], s.tra[1], s.tra[2]); double alpha; Point3d axis; s.rot.ToAxis(alpha, axis); glRotated(math::ToDeg(alpha), axis[0], axis[1], axis[2]); glScaled(s.sca, s.sca, s.sca); } inline void glGetv(const GLenum pname, Eigen::Matrix& matrix){ glGetFloatv(pname,matrix.data()); } inline void glGetv(const GLenum pname, Eigen::Matrix& matrix){ glGetDoublev(pname,matrix.data()); } inline void glGetv(const GLenum pname, Eigen::Matrix& matrix){ glGetFloatv(pname,matrix.data()); matrix.transposeInPlace(); } inline void glGetv(const GLenum pname, Eigen::Matrix& matrix){ glGetDoublev(pname,matrix.data()); matrix.transposeInPlace(); } template inline void glGetv(const GLenum pname, const Eigen::Transform& t) { glGetv(pname,t.matrix()); } }//namespace #endif #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/pick.h0000644000175000017500000003125711517500604017005 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.10 2006/12/07 00:39:22 cignoni Added a class prototype for avoiding the inclusion of tetra.h Revision 1.9 2006/12/04 09:27:13 cignoni Removed useless include ****************************************************************************/ #ifndef __PICK______H #define __PICK______H #include #include namespace vcg{ template class GLPickTri { typedef typename MESH_TYPE::FaceIterator FaceIterator; typedef typename MESH_TYPE::VertexIterator VertexIterator; typedef typename MESH_TYPE::FacePointer FacePointer; typedef typename MESH_TYPE::VertexPointer VertexPointer; typedef typename MESH_TYPE::VertexType VertexType; public: static bool PickNearestFace(int x, int y, MESH_TYPE &m, FacePointer &fi,int width=4, int height=4) { std::vector result; int val=PickFace(x,y,m,result,width,height); if(val!=0) { fi=result[0]; return true; } fi=NULL; return false; } static int PickVert(int x, int y, MESH_TYPE &m, std::vector &result, int width=4, int height=4,bool sorted=true) { result.clear(); if(width==0 ||height==0) return 0; long hits; int sz=m.vert.size()*5; GLuint *selectBuf =new GLuint[sz]; glSelectBuffer(sz, selectBuf); glRenderMode(GL_SELECT); glInitNames(); /* Because LoadName() won't work with no names on the stack */ glPushName(-1); double mp[16]; GLint viewport[4]; glGetIntegerv(GL_VIEWPORT,viewport); glMatrixMode(GL_PROJECTION); glGetDoublev(GL_PROJECTION_MATRIX ,mp); glPushMatrix(); glLoadIdentity(); gluPickMatrix(x, y, width, height, viewport); glMultMatrixd(mp); glMatrixMode(GL_MODELVIEW); glPushMatrix(); int vcnt=0; VertexIterator vi; for(vi=m.vert.begin();vi!=m.vert.end();++vi) { if(!(*vi).IsD()) { glLoadName(vcnt); glBegin(GL_POINTS); glVertex( (*vi).P() ); glEnd(); } vcnt++; // the counter should advance even for deleted faces! } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); hits = glRenderMode(GL_RENDER); std::vector< std::pair > H; for(long ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); } if(sorted) std::sort(H.begin(),H.end()); result.resize(H.size()); for(long ii=0;ii &result, int width=4, int height=4,bool sorted=true) { result.clear(); if(width==0 ||height==0) return 0; long hits; int sz=m.face.size()*5; GLuint *selectBuf =new GLuint[sz]; // static unsigned int selectBuf[16384]; glSelectBuffer(sz, selectBuf); glRenderMode(GL_SELECT); glInitNames(); /* Because LoadName() won't work with no names on the stack */ glPushName(-1); double mp[16]; GLint viewport[4]; glGetIntegerv(GL_VIEWPORT,viewport); glMatrixMode(GL_PROJECTION); glGetDoublev(GL_PROJECTION_MATRIX ,mp); glPushMatrix(); glLoadIdentity(); //gluPickMatrix(x, viewport[3]-y, 4, 4, viewport); gluPickMatrix(x, y, width, height, viewport); glMultMatrixd(mp); glMatrixMode(GL_MODELVIEW); glPushMatrix(); int fcnt=0; FaceIterator fi; for(fi=m.face.begin();fi!=m.face.end();++fi) { if(!(*fi).IsD()) { glLoadName(fcnt); glBegin(GL_TRIANGLES); glVertex( (*fi).V(0)->P() ); glVertex( (*fi).V(1)->P() ); glVertex( (*fi).V(2)->P() ); glEnd(); } fcnt++; // the counter should advance even for deleted faces! } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); hits = glRenderMode(GL_RENDER); //xstring buf; //if (hits <= 0) return 0; std::vector< std::pair > H; for(long ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); } if(sorted) std::sort(H.begin(),H.end()); // if(H.size()>0) TRACE("\n Closest is %i\n",H[0].second); result.resize(H.size()); for(long ii=0;ii &resultZ, int width=4, int height=4, bool sorted=true) { // First step double mm[16]; double mp[16]; GLint vp[4]; glGetIntegerv(GL_VIEWPORT,vp); glGetDoublev(GL_MODELVIEW_MATRIX ,mm); glGetDoublev(GL_PROJECTION_MATRIX ,mp); int screenW = vp[2]-vp[0]; int screenH = vp[3]-vp[1]; GLfloat *buffer = new GLfloat[screenW*screenH]; glReadPixels(vp[0],vp[1],vp[2],vp[3],GL_DEPTH_COMPONENT,GL_FLOAT,buffer); std::vector result; PickFace(x,y,m,result,width,height,sorted); float LocalEpsilon = 0.001f; for(size_t i =0;i=0 && tx=0 && ty= tz) resultZ.push_back(result[i]); } } delete [] buffer; return resultZ.size(); } }; ////////////////////////////////////////////////////////////////////////// template class GLPickTetra { typedef typename TETRA_MESH_TYPE::TetraIterator TetraIterator; typedef typename TETRA_MESH_TYPE::TetraPointer TetraPointer; typedef typename TETRA_MESH_TYPE::VertexType VertexType; public: static bool PickNearestTetra(int x, int y,TETRA_MESH_TYPE &m, TetraIterator &ti,int width=4, int height=4) { std::vector result; int val=PickTetra(x,y,m,result,width,height); if(val!=0) { ti=result[0]; return true; } ti=0; return false; } // class prototype needed for avoid the inclusion of tetra.h class Tetra; static int PickTetra(int x, int y, TETRA_MESH_TYPE &m, std::vector &result, int width=4, int height=4) { result.clear(); long hits; int sz=m.tetra.size()*5; unsigned int *selectBuf =new unsigned int[sz]; // static unsigned int selectBuf[16384]; glSelectBuffer(sz, selectBuf); glRenderMode(GL_SELECT); glInitNames(); /* Because LoadName() won't work with no names on the stack */ glPushName(-1); double mp[16]; int viewport[4]; glGetIntegerv(GL_VIEWPORT,viewport); glMatrixMode(GL_PROJECTION); glGetDoublev(GL_PROJECTION_MATRIX ,mp); glPushMatrix(); glLoadIdentity(); //gluPickMatrix(x, viewport[3]-y, 4, 4, viewport); gluPickMatrix(x, y, width, height, viewport); glMultMatrixd(mp); glMatrixMode(GL_MODELVIEW); glPushMatrix(); int tetracnt=0; TetraIterator ti; for(ti=m.tetra.begin();ti!=m.tetra.end();++ti) { if(!(*ti).IsD()) { glLoadName(tetracnt); glBegin(GL_TRIANGLES); for (int face=0;face<4;face++) { //glLoadName(tetracnt); VertexType *v0=ti->V(Tetra::VofF(face,0)); VertexType *v1=ti->V(Tetra::VofF(face,1)); VertexType *v2=ti->V(Tetra::VofF(face,2)); glVertex(v0->P()); glVertex(v1->P()); glVertex(v2->P()); } glEnd(); tetracnt++; } } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); hits = glRenderMode(GL_RENDER); //xstring buf; //if (hits <= 0) return 0; std::vector< std::pair > H; int ii; for(ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); } std::sort(H.begin(),H.end()); // if(H.size()>0) TRACE("\n Closest is %i\n",H[0].second); result.resize(H.size()); for(ii=0;ii > result; int val=PickTetraFace(x,y,m,result,width,height); if(val!=0) { ti=result[0].first; face=result[0].second; return true; } ti=0; face=-1; return false; } static int PickTetraFace(int x, int y, TETRA_MESH_TYPE &m, std::vector > &result, int width=4, int height=4) { result.clear(); long hits; int sz=(m.tetra.size()*4)*5; unsigned int *selectBuf =new unsigned int[sz]; // static unsigned int selectBuf[16384]; glSelectBuffer(sz, selectBuf); glRenderMode(GL_SELECT); glInitNames(); /* Because LoadName() won't work with no names on the stack */ glPushName(-1); double mp[16]; int viewport[4]; glGetIntegerv(GL_VIEWPORT,viewport); glMatrixMode(GL_PROJECTION); glGetDoublev(GL_PROJECTION_MATRIX ,mp); glPushMatrix(); glLoadIdentity(); //gluPickMatrix(x, viewport[3]-y, 4, 4, viewport); gluPickMatrix(x, y, width, height, viewport); glMultMatrixd(mp); glMatrixMode(GL_MODELVIEW); glPushMatrix(); int tetracnt=0; TetraIterator ti; VertexType *v0; VertexType *v1; VertexType *v2; int face; for(ti=m.tetra.begin();ti!=m.tetra.end();++ti) { if(!(*ti).IsD()) { for (face=0;face<4;face++){ v0=ti->V(Tetra::VofF(face,0)); v1=ti->V(Tetra::VofF(face,1)); v2=ti->V(Tetra::VofF(face,2)); glLoadName(tetracnt); glBegin(GL_TRIANGLES); glVertex(v0->P()); glVertex(v1->P()); glVertex(v2->P()); glEnd(); tetracnt++; } } } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); hits = glRenderMode(GL_RENDER); //xstring buf; //if (hits <= 0) return 0; std::vector< std::pair > H; int ii; for(ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); } std::sort(H.begin(),H.end()); // if(H.size()>0) TRACE("\n Closest is %i\n",H[0].second); result.resize(H.size()); for(ii=0;ii(&*ti,index%4); } delete [] selectBuf; return result.size(); } }; } #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/deprecated_space.h0000644000175000017500000002744111517500604021332 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.10 2007/07/31 12:21:50 ganovelli added gltetra, added normal gltriangle Revision 1.9 2007/05/08 18:55:38 ganovelli glTriangle added Revision 1.8 2007/01/18 01:26:23 cignoni Added cast for mac compiling Revision 1.7 2005/10/13 08:32:26 cignoni Added glscale(scalar) and corrected bug in glscale(point2) Revision 1.6 2005/06/30 10:17:04 ganovelli added draw plane Revision 1.5 2005/05/05 12:28:13 cignoni added glboxwire Revision 1.4 2004/07/07 23:30:28 cignoni Added box3 drawing functions Revision 1.3 2004/05/26 15:13:01 cignoni Removed inclusion of gl extension stuff and added glcolor stuff Revision 1.2 2004/05/13 23:44:47 ponchio --> Revision 1.1 2004/04/05 11:56:14 cignoni First working version! ****************************************************************************/ #ifndef VCG_GL_SPACE_H #define VCG_GL_SPACE_H // Please note that this file assume that you have already included your // gl-extension wrapping utility, and that therefore all the extension symbol are already defined. #include #include #include #include #include #include #include namespace vcg { inline void glScale(float const & p){ glScalef(p,p,p);} inline void glScale(double const & p){ glScaled(p,p,p);} inline void glVertex(Point2 const & p) { glVertex2iv((const GLint*)p.V());} inline void glVertex(Point2 const & p) { glVertex2sv(p.V());} inline void glVertex(Point2 const & p) { glVertex2fv(p.V());} inline void glVertex(Point2 const & p){ glVertex2dv(p.V());} inline void glTexCoord(Point2 const & p) { glTexCoord2iv((const GLint*)p.V());} inline void glTexCoord(Point2 const & p) { glTexCoord2sv(p.V());} inline void glTexCoord(Point2 const & p) { glTexCoord2fv(p.V());} inline void glTexCoord(Point2 const & p){ glTexCoord2dv(p.V());} inline void glTranslate(Point2 const & p) { glTranslatef(p[0],p[1],0);} inline void glTranslate(Point2 const & p){ glTranslated(p[0],p[1],0);} inline void glScale(Point2 const & p) { glScalef(p[0],p[1],1.0);} inline void glScale(Point2 const & p){ glScaled(p[0],p[1],1.0);} inline void glVertex(Point3 const & p) { glVertex3iv((const GLint*)p.V());} inline void glVertex(Point3 const & p) { glVertex3sv(p.V());} inline void glVertex(Point3 const & p) { glVertex3fv(p.V());} inline void glVertex(Point3 const & p){ glVertex3dv(p.V());} inline void glNormal(Point3 const & p) { glNormal3iv((const GLint*)p.V());} inline void glNormal(Point3 const & p) { glNormal3sv(p.V());} inline void glNormal(Point3 const & p) { glNormal3fv(p.V());} inline void glNormal(Point3 const & p){ glNormal3dv(p.V());} inline void glTexCoord(Point3 const & p) { glTexCoord3iv((const GLint*)p.V());} inline void glTexCoord(Point3 const & p) { glTexCoord3sv(p.V());} inline void glTexCoord(Point3 const & p) { glTexCoord3fv(p.V());} inline void glTexCoord(Point3 const & p){ glTexCoord3dv(p.V());} inline void glTranslate(Point3 const & p) { glTranslatef(p[0],p[1],p[2]);} inline void glTranslate(Point3 const & p){ glTranslated(p[0],p[1],p[2]);} inline void glScale(Point3 const & p) { glScalef(p[0],p[1],p[2]);} inline void glScale(Point3 const & p){ glScaled(p[0],p[1],p[2]);} inline void glColor(Color4b const & c) { glColor4ubv(c.V());} inline void glColor(Color4f const & c) { glColor4fv (c.V());} inline void glColor(Color4d const & c) { glColor4dv (c.V());} inline void glClearColor(Color4b const &c) { ::glClearColor(float(c[0])/255.0f,float(c[1])/255.0f,float(c[2])/255.0f,1.0f);} inline void glClearColor(Color4f const &c) { ::glClearColor(c[0],c[1],c[2],c[3]); } inline void glClearColor(Color4d const &c) { ::glClearColor(float(c[0]),float(c[1]),float(c[2]),float(c[3])); } inline void glLight(GLenum light, GLenum pname, Color4b const & c) { static float cf[4]; cf[0]=float(cf[0]/255.0); cf[1]=float(c[1]/255.0); cf[2]=float(c[2]/255.0); cf[3]=float(c[3]/255.0); glLightfv(light,pname,cf); } template inline void glBoxWire(Box3 const & b) { glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glBegin(GL_LINE_STRIP); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.min[2]); glVertex3f((float)b.max[0],(float)b.min[1],(float)b.min[2]); glVertex3f((float)b.max[0],(float)b.max[1],(float)b.min[2]); glVertex3f((float)b.min[0],(float)b.max[1],(float)b.min[2]); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.min[2]); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.max[2]); glVertex3f((float)b.max[0],(float)b.min[1],(float)b.max[2]); glVertex3f((float)b.max[0],(float)b.max[1],(float)b.max[2]); glVertex3f((float)b.min[0],(float)b.max[1],(float)b.max[2]); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.max[2]); glEnd(); glBegin(GL_LINES); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.min[2]); glVertex3f((float)b.min[0],(float)b.min[1],(float)b.max[2]); glVertex3f((float)b.max[0],(float)b.min[1],(float)b.min[2]); glVertex3f((float)b.max[0],(float)b.min[1],(float)b.max[2]); glVertex3f((float)b.max[0],(float)b.max[1],(float)b.min[2]); glVertex3f((float)b.max[0],(float)b.max[1],(float)b.max[2]); glVertex3f((float)b.min[0],(float)b.max[1],(float)b.min[2]); glVertex3f((float)b.min[0],(float)b.max[1],(float)b.max[2]); glEnd(); glPopAttrib(); }; template /// Funzione di utilita' per la visualizzazione in OpenGL (flat shaded) inline void glBoxFlat(Box3 const & b) { glPushAttrib(GL_SHADE_MODEL); glShadeModel(GL_FLAT); glBegin(GL_QUAD_STRIP); glNormal3f(.0f,.0f,1.0f); glVertex3f(b.min[0], b.max[1], b.max[2]); glVertex3f(b.min[0], b.min[1], b.max[2]); glVertex3f(b.max[0], b.max[1], b.max[2]); glVertex3f(b.max[0], b.min[1], b.max[2]); glNormal3f(1.0f,.0f,.0f); glVertex3f(b.max[0], b.max[1], b.min[2]); glVertex3f(b.max[0], b.min[1], b.min[2]); glNormal3f(.0f,.0f,-1.0f); glVertex3f(b.min[0], b.max[1], b.min[2]); glVertex3f(b.min[0], b.min[1], b.min[2]); glNormal3f(-1.0f,.0f,.0f); glVertex3f(b.min[0], b.max[1], b.max[2]); glVertex3f(b.min[0], b.min[1], b.max[2]); glEnd(); glBegin(GL_QUADS); glNormal3f(.0f,1.0f,.0f); glVertex3f(b.min[0], b.max[1], b.max[2]); glVertex3f(b.max[0], b.max[1], b.max[2]); glVertex3f(b.max[0], b.max[1], b.min[2]); glVertex3f(b.min[0], b.max[1], b.min[2]); glNormal3f(.0f,-1.0f,.0f); glVertex3f(b.min[0], b.min[1], b.min[2]); glVertex3f(b.max[0], b.min[1], b.min[2]); glVertex3f(b.max[0], b.min[1], b.max[2]); glVertex3f(b.min[0], b.min[1], b.max[2]); glEnd(); glPopAttrib(); }; template /// Setta i sei clip planes di opengl a far vedere solo l'interno del box inline void glBoxClip(const Box3 & b) { double eq[4]; eq[0]= 1; eq[1]= 0; eq[2]= 0; eq[3]=(double)-b.min[0]; glClipPlane(GL_CLIP_PLANE0,eq); eq[0]=-1; eq[1]= 0; eq[2]= 0; eq[3]=(double) b.max[0]; glClipPlane(GL_CLIP_PLANE1,eq); eq[0]= 0; eq[1]= 1; eq[2]= 0; eq[3]=(double)-b.min[1]; glClipPlane(GL_CLIP_PLANE2,eq); eq[0]= 0; eq[1]=-1; eq[2]= 0; eq[3]=(double) b.max[1]; glClipPlane(GL_CLIP_PLANE3,eq); eq[0]= 0; eq[1]= 0; eq[2]= 1; eq[3]=(double)-b.min[2]; glClipPlane(GL_CLIP_PLANE4,eq); eq[0]= 0; eq[1]= 0; eq[2]=-1; eq[3]=(double) b.max[2]; glClipPlane(GL_CLIP_PLANE5,eq); } template inline void glBoxWire(const Box2 & b) { glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glBegin(GL_LINE_LOOP); glVertex2f((float)b.min[0],(float)b.min[1]); glVertex2f((float)b.max[0],(float)b.min[1]); glVertex2f((float)b.max[0],(float)b.max[1]); glVertex2f((float)b.min[0],(float)b.max[1]); glEnd(); glPopAttrib(); }; template inline void glPlane3( Plane3 p, Point3 c, T size ) { Point3 w = p.Direction(); Point3 u,v,c1; GetUV(w,u,v); c1 = p.Projection(c); u.Normalize(); w.Normalize(); v.Normalize(); Matrix44 m; *(Point3*)&m[0][0] = *(Point3*)&u[0];m[0][3]=0; *(Point3*)&m[1][0] = *(Point3*)&w[0];m[1][3]=0; *(Point3*)&m[2][0] = *(Point3*)&v[0];m[2][3]=0; *(Point3*)&m[3][0] = *(Point3*)&c1[0];m[3][3]=1; glPushMatrix(); glMultMatrix(m.transpose()); glBegin(GL_QUADS); glNormal(Point3(0,1,0)); glVertex(Point3(-size,0,-size)); glVertex(Point3(size ,0,-size)); glVertex(Point3(size ,0, size)); glVertex(Point3(-size,0, size)); glEnd(); glPopMatrix(); } template inline void glTriangle3( TriangleType & c ) { vcg::Point3 n = vcg::Normal(c); glBegin(GL_TRIANGLES); glNormal(n); glVertex(c.P(0)); glVertex(c.P(1)); glVertex(c.P(2)); glEnd(); } template inline void glTetra3( TetraType & c ) { glTriangle3(Triangle3(c.P(0),c.P(1),c.P(2))); glTriangle3(Triangle3(c.P(1),c.P(3),c.P(2))); glTriangle3(Triangle3(c.P(0),c.P(2),c.P(3))); glTriangle3(Triangle3(c.P(1),c.P(0),c.P(3))); } #ifdef VCG_USE_EIGEN template struct EvalToKnownPointType; template struct EvalToKnownPointType { typedef Point2 Type; }; template struct EvalToKnownPointType { typedef Point3 Type; }; template struct EvalToKnownPointType { typedef Point4 Type; }; #define _WRAP_EIGEN_XPR(FUNC) template \ inline void FUNC(const Eigen::MatrixBase& p) { \ FUNC(typename EvalToKnownPointType::Type(p)); } _WRAP_EIGEN_XPR(glVertex) _WRAP_EIGEN_XPR(glNormal) _WRAP_EIGEN_XPR(glTexCoord) _WRAP_EIGEN_XPR(glTranslate) _WRAP_EIGEN_XPR(glScale) #endif }//namespace #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/deprecated_math.h0000644000175000017500000000762411732414760021177 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef VCG_GL_MATH_H #define VCG_GL_MATH_H // Please note that this file assume that you have already included your // gl-extension wrapping utility, and that therefore all the extension symbol are already defined. #include #include //#include // please do not include it! namespace vcg { inline void glMultMatrixE(const Matrix44f &matrix) { glMultMatrixf((const GLfloat *)(matrix.transpose().V())); } inline void glMultMatrix(const Matrix44f &matrix) { glMultMatrixf((const GLfloat *)(matrix.transpose().V())); } inline void glMultMatrixE(const Matrix44d &matrix) { glMultMatrixd((const GLdouble *)(matrix.transpose().V())); } inline void glMultMatrix(const Matrix44d &matrix) { glMultMatrixd((const GLdouble *)(matrix.transpose().V())); } inline void glLoadMatrix(const Matrix44d &matrix) { glLoadMatrixd((const GLdouble *)(matrix.transpose().V())); } inline void glLoadMatrix(const Matrix44f &matrix) { glLoadMatrixf((const GLfloat *)(matrix.transpose().V())); } inline void glMultMatrixDirect(const Matrix44f &matrix) { glMultMatrixf((const GLfloat *)(matrix.V())); } inline void glMultMatrixDirect(const Matrix44d &matrix) { glMultMatrixd((const GLdouble *)(matrix.V())); } inline void glMultMatrix(const Similarityf &s) { glTranslatef(s.tra[0], s.tra[1], s.tra[2]); glScalef(s.sca, s.sca, s.sca); float alpha; Point3f axis; s.rot.ToAxis(alpha, axis); glRotatef(math::ToDeg(alpha), axis[0], axis[1], axis[2]); } inline void glMultMatrix(const Similarityd &s) { glTranslated(s.tra[0], s.tra[1], s.tra[2]); double alpha; Point3d axis; s.rot.ToAxis(alpha, axis); glRotated(math::ToDeg(alpha), axis[0], axis[1], axis[2]); glScaled(s.sca, s.sca, s.sca); } inline void glGetv(const GLenum pname, Matrix44f & m){ Matrix44f tmp; glGetFloatv(pname,tmp.V()); m = tmp.transpose(); } inline void glGetv(const GLenum pname, Matrix44d & m){ Matrix44d tmp; glGetDoublev(pname,tmp.V()); m = tmp.transpose(); } inline void glGetDirectv(const GLenum pname, Matrix44f & m){ glGetFloatv(pname,m.V()); } inline void glGetDirecv(const GLenum pname, Matrix44d & m){ glGetDoublev(pname,m.V()); } }//namespace #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/pos.h0000644000175000017500000000653311517500604016657 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.1 2006/12/10 19:59:28 ganovelli first draft of the class the draw a Pos ****************************************************************************/ #ifndef VCG_GL_POS_H #define VCG_GL_POS_H // Please note that this file assume that you have already included your // gl-extension wrapping utility, and that therefore all the extension symbol are already defined. #include #include namespace vcg { template struct GlPos{ typedef typename PosType::ScalarType S; static void Draw(PosType & p){ Point3 bc = Barycenter(*(p.f)); Point3 mid = (p.f->P(p.z)+p.f->P(((p.z+1)%3)))*0.5f; Point3 up = ((bc- p.v->P()) ^ (mid- p.f->P(p.z) )).Normalize(); Point3 ax = ( up ^ (mid-p.f->P(p.z)) ) .Normalize(); S proj = (bc-mid)*(ax)*0.5; Point3 bc1 = mid+ (ax)*proj; glBegin(GL_TRIANGLES); glVertex(p.v->P()); if( p.v == p.f->V(p.z)) { glVertex(mid); glVertex(bc1);} else {glVertex(bc1); glVertex(mid);} glEnd(); } }; template struct GlVfIterator{ typedef typename VfIteType::ScalarType S; static void Draw(VfIteType & v){ Point3 p = v.F()->P(v.I());// anchor Point3 c[3]; for(int i = 0; i < 3;++i) { c[i] = v.F()->P(i)*0.9 + v.F()->P1(i)*0.05 + v.F()->P2(i)*0.05; if(v.F()->VFp(i) != NULL) { glBegin(GL_LINES); glVertex(c[i]); glVertex( vcg::Barycenter(*(v.F()->VFp(i)))); glEnd(); } } } }; }//namespace #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/addons.h0000644000175000017500000003067511517500604017332 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.12 2006/05/25 09:22:58 cignoni Removed all GLUT dependencies! Revision 1.11 2006/03/29 07:54:03 cignoni Wrong matrix type in cone (thx Maarten) ****************************************************************************/ #ifndef __VCG_GLADDONS #define __VCG_GLADDONS #include #include #include #include namespace vcg { #include "gl_geometry.h" /** Class Add_Ons. This is class draw 3d icons on the screen */ class Add_Ons { public: enum DrawMode {DMUser,DMWire,DMSolid} ; private: ///used to find right transformation in case of rotation static void XAxis(vcg::Point3f zero, vcg::Point3f uno, Matrix44f & tr) { #ifndef VCG_USE_EIGEN tr.SetZero(); *((vcg::Point3f*)&tr[0][0]) = uno-zero; GetUV(*((vcg::Point3f*)tr[0]),*((vcg::Point3f*)tr[1]),*((vcg::Point3f*)tr[2])); tr[3][3] = 1.0; *((vcg::Point3f*)&tr[3][0]) = zero; #else tr.col(0).start<3>().setZero(); tr.row(0).start<3>() = (uno-zero).normalized(); // n tr.row(1).start<3>() = tr.row(0).start<3>().unitOrthogonal(); // u tr.row(2).start<3>() = tr.row(0).start<3>().cross(tr.row(1).start<3>()).normalized(); // v tr.row(3) << zero.transpose(), 1.; #endif } //set drawingmode parameters static void SetGLParameters(DrawMode DM) { switch(DM) { case DMUser : break; case DMWire : glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); glDisable(GL_NORMALIZE); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); break; case DMSolid : glDisable(GL_CULL_FACE); glPolygonMode(GL_FRONT,GL_FILL); break; default : break; } } ///draw a cylinder static void Cylinder(int slices,float lenght,float width,bool useDisplList) { static std::map Disp_listMap; GLint cyl_List=-1; std::map::const_iterator it=Disp_listMap.find(slices); ///if the diplay list is createdtake the Glint that identify it bool to_insert=false; if (useDisplList) { if (it!=Disp_listMap.end())///the list exist cyl_List=it->second; else to_insert=true; } glScaled(lenght,width,width); if (((!glIsList(cyl_List))&&(useDisplList))||(!useDisplList)) { if (useDisplList) { cyl_List = glGenLists(1); glNewList(cyl_List, GL_COMPILE); } int b; vcg::Point3f p0; vcg::Point3f p1; float step=6.28f/(float)slices; float angle=0; glBegin(GL_TRIANGLE_STRIP); for(b = 0; b <= slices-1; ++b){ p0 = vcg::Point3f( 0, sin(angle),cos(angle)); p1 = p0; p1[0] = 1.f; glNormal3f(p0[0],p0[1],p0[2]); glVertex3d(p0[0],p0[1],p0[2]); glVertex3d(p1[0],p1[1],p1[2]); angle+=step; } ///re-conjunction with first point of cylinder glNormal3f(0,0,1); glVertex3d(0,0,1); glVertex3d(1,0,1); glEnd(); ///fill the cylinder down angle=0; p0=vcg::Point3f(0,0,0); glBegin(GL_TRIANGLE_FAN); glNormal3f(-1,0,0); glVertex3d(p0[0],p0[1],p0[2]); for(b = 0; b <= slices-1; ++b){ glNormal3f(-1,0,0); p1 = Point3f( 0, sin(angle),cos(angle)); glVertex3d(p1[0],p1[1],p1[2]); angle+=step; } glNormal3f(-1,0,0); glVertex3d(0,0,1); glEnd(); angle=0; p0=vcg::Point3f(1,0,0); glBegin(GL_TRIANGLE_FAN); glNormal3f(1,0,0); glVertex3d(p0[0],p0[1],p0[2]); for(b = 0; b <= slices-1; ++b){ glNormal3f(1,0,0); p1 = Point3f( 1, sin(angle),cos(angle)); glVertex3d(p1[0],p1[1],p1[2]); angle+=step; } glNormal3f(1,0,0); glVertex3d(1,0,1); glEnd(); if (useDisplList) glEndList(); } if (useDisplList) { glCallList(cyl_List); ///I insert key and value in the map if I need if (to_insert) Disp_listMap.insert(std::pair(slices,cyl_List)); } } public: static void Diamond (float radius,bool useDisplList) { static GLint diam_List=-1; glScaled(radius,radius,radius); if (((!glIsList(diam_List))&&(useDisplList))||(!useDisplList)) { if (useDisplList) { diam_List = glGenLists(1); glNewList(diam_List, GL_COMPILE); } glBegin(GL_TRIANGLE_FAN); glNormal3f( 0.0, 1, 0.0); glVertex3f(0.0,1,0.0); glNormal3f( 1, 0.0, 0.0); glVertex3f( 1, 0.0, 0.0); glNormal3f( 0.0, 0.0, -1); glVertex3f( 0.0, 0.0,-1); glNormal3f(-1, 0.0 , 0.0); glVertex3f(-1, 0.0, 0.0); glNormal3f( 0.0, 0.0, 1); glVertex3f( 0.0, 0.0, 1); glNormal3f( 1, 0.0, 0.0); glVertex3f( 1, 0.0, 0.0); glEnd(); glBegin(GL_TRIANGLE_FAN); glNormal3f( 0.0, 1, 0.0); glVertex3f( 0.0,-1, 0.0); glNormal3f( 1, 0.0, 0.0); glVertex3f( 1, 0.0, 0.0); glNormal3f( 0.0, 0.0, 1); glVertex3f( 0.0, 0.0, 1); glNormal3f(-1,0.0 , 0.0); glVertex3f(-1, 0.0, 0.0); glNormal3f( 0.0,0.0, -1); glVertex3f( 0.0, 0.0,-1); glNormal3f( 1, 0.0, 0.0); glVertex3f( 1, 0.0, 0.0); glEnd(); if (useDisplList) glEndList(); } if (useDisplList) glCallList(diam_List); } ///draw a cone static void Cone(int slices,float lenght,float width,bool useDisplList) { assert(!glGetError()); static std::map Disp_listMap; GLint cone_List=-1; std::map::const_iterator it=Disp_listMap.find(slices); ///if the diplay list is createdtake the Glint that identify it bool to_insert=false; if (useDisplList) { if (it!=Disp_listMap.end())///the list exist cone_List=it->second; else to_insert=true; } glScaled(lenght,width,width); assert(!glGetError()); if (((!glIsList(cone_List))&&(useDisplList))||(!useDisplList)) { int h=1; vcg::Point3f p0; vcg::Point3f P[2]; vcg::Point3f N[2]; assert(!glGetError()); glScaled(lenght,width,width); if (useDisplList) { cone_List = glGenLists(1); glNewList(cone_List, GL_COMPILE); } for(h=0; h < 2; ++h) { assert(!glGetError()); //glBegin(GL_TRIANGLE_FAN); p0 = Point3f(0,0,0); if(h==0) p0[0]+=1.f; //glNormal3f(1,0.0,0.0); //glVertex3d(p0[0],p0[1],p0[2]); N[0]= Point3f( 1.f,sinf(0),cosf(0) ); P[0]= Point3f( 0,sinf(0),cosf(0)); int b; for(b = 1; b <= slices; ++b) { float angle = -6.28f*(float)b/(float)slices; if (b==slices) angle=0; N[1] = Point3f( 1.f, sinf(angle), cosf(angle) ); P[1] = Point3f( 0, sinf(angle), cosf(angle)); assert(!glGetError()); glBegin(GL_TRIANGLES); Point3f n = ( (P[0]-p0) ^ (P[2]-p0) ).Normalize(); glNormal3f(n[0],n[1],n[2]); glVertex3f(p0[0],p0[1],p0[2]); glNormal3f(N[0][0],N[0][1],N[0][2]); glVertex3f(P[0][0],P[0][1],P[0][2]); glNormal3f(N[1][0],N[1][1],N[1][2]); glVertex3f(P[1][0],P[1][1],P[1][2]); glEnd(); assert(!glGetError()); N[0] = N[1]; P[0] = P[1]; } //glEnd(); } if (useDisplList) glEndList(); } if (useDisplList) { glCallList(cone_List); ///I insert key and value in the map if I need if (to_insert) Disp_listMap.insert(std::pair(slices,cone_List)); } } public: /// draw an arrow from tail to head /// body_width = width of the body of arrow /// head_lenght = lenght of the head of arrow /// head_width = width of the head of arrow /// body_slice = number of slices on the body /// head_slice = number of slices on the head template static void glArrow(Point3f tail, Point3f head,float body_width,float head_lenght, float head_width,int body_slice=10,int head_slice=10,bool useDisplList=true) { if (tail!=head) { //assert(!glGetError()); Matrix44f tr; XAxis(tail,head,tr); glPushAttrib(GL_ALL_ATTRIB_BITS); SetGLParameters(dm); glPushMatrix(); glMultMatrixf(&tr[0][0]); vcg::Point3f Direct=(head-tail); float l_body=Direct.Norm()-head_lenght; glPushMatrix(); //glTranslate(vcg::Point3f(tail.Norm(),0,0)); Cylinder(body_slice,l_body,body_width,useDisplList); glPopMatrix(); glTranslate(vcg::Point3f(l_body,0,0)); Cone(head_slice,head_lenght,head_width,useDisplList); glPopMatrix(); //assert(!glGetError()); glPopAttrib(); //assert(!glGetError()); } } /// draw a cone from tail to head /// width = width of the base of the cone /// slice = number of slices on the cone template static void glCone(Point3f tail, Point3f head,float width,int slice=10,bool useDisplList=true) { if (tail!=head) { Matrix44f tr; XAxis(tail,head,tr); glPushAttrib(GL_ALL_ATTRIB_BITS); SetGLParameters(dm); glPushMatrix(); glMultMatrixf(&tr[0][0]); vcg::Point3f Direct=(head-tail); float l_body=Direct.Norm(); //glTranslate(vcg::Point3f(tail.Norm(),0,0)); Cone(slice,l_body,width,useDisplList); glPopMatrix(); glPopAttrib(); } } /// draw a cylinder from tail to head /// width = width of the base of the cylinder /// slice = number of slices on the cylinder template static void glCylinder(Point3f tail, Point3f head,float width,int slice=10,bool useDisplList=true) { if (tail!=head) { Matrix44f tr; XAxis(tail,head,tr); glPushAttrib(GL_ALL_ATTRIB_BITS); SetGLParameters(dm); glPushMatrix(); glMultMatrixf(&tr[0][0]); vcg::Point3f Direct=(head-tail); float l_body=Direct.Norm(); //glTranslate(vcg::Point3f(tail.Norm(),0,0)); Cylinder(slice,l_body,width,useDisplList); glPopMatrix(); glPopAttrib(); } } /// draw a point in Center /// size = Radius of the point /// slices = The number of subdivisions around the Z axis (similar to lines of longitude). /// stacks = The number of subdivisions along the Z axis (similar to lines of latitude). template static void glPoint(vcg::Point3f Center,float size,int slices =16,int stacks =16) { if (size!=0){ glPushMatrix(); glTranslate(Center); if (dm==DMWire) glutWireSphere(size,slices,stacks); else if (dm==DMSolid) glutSolidSphere(size,slices,stacks); else glutSolidSphere(size,slices,stacks); glPopMatrix(); } } /// draw a point in Center /// size = Radius of the point /// slices = The number of subdivisions around the Z axis (similar to lines of longitude). /// stacks = The number of subdivisions along the Z axis (similar to lines of latitude). template static void glDiamond (Point3f Center, float size,bool useDisplList=true) { if (size!=0){ glPushAttrib(GL_ALL_ATTRIB_BITS); SetGLParameters(dm); glPushMatrix(); glTranslated(Center[0],Center[1],Center[2]); Diamond(size,useDisplList); glPopMatrix(); glPopAttrib(); } } }; } #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/splatting_apss/0000755000175000017500000000000012227522351020733 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/wrap/gl/splatting_apss/splatrenderer.qrc0000644000175000017500000000025611517500604024315 0ustar gladkgladk shaders/Raycasting.glsl shaders/Finalization.glsl meshlab-1.3.2+dfsg1/vcglib/wrap/gl/splatting_apss/shaders/0000755000175000017500000000000012227522351022364 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/wrap/gl/splatting_apss/shaders/Finalization.glsl0000644000175000017500000000734611517500604025706 0ustar gladkgladk/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * 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. * * * ****************************************************************************/ #extension GL_ARB_texture_rectangle : enable #ifndef EXPE_DEPTH_INTERPOLATION #define EXPE_DEPTH_INTERPOLATION 0 #endif #ifndef EXPE_OUTPUT_DEPTH #define EXPE_OUTPUT_DEPTH 0 #endif // avoid an annoying bug with the nvidia driver 87XX serie. #define epsilon 0.000001 uniform vec4 viewport; #ifndef EXPE_DEFERRED_SHADING uniform sampler2DRect ColorWeight; #if (EXPE_OUTPUT_DEPTH==1) uniform sampler2DRect Depth; #endif void Finalization(void) { vec4 color = texture2DRect(ColorWeight, gl_FragCoord.st - viewport.xy + epsilon); #if (EXPE_OUTPUT_DEPTH==1) gl_FragDepth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; #endif if (color.w<0.001) discard; gl_FragColor = color/color.w; gl_FragColor.a = 1.; } #else uniform vec2 unproj; uniform sampler2DRect ColorWeight; uniform sampler2DRect NormalWeight; #if ( (EXPE_DEPTH_INTERPOLATION==0) || (EXPE_OUTPUT_DEPTH==1)) uniform sampler2DRect Depth; #endif void Finalization(void) { vec4 color = texture2DRect(ColorWeight, gl_FragCoord.st - viewport.xy + epsilon); if (color.w<0.001) discard; if(color.w>0.001) color.xyz /= color.w; vec3 viewVec = normalize(gl_TexCoord[0].xyz); vec4 normaldepth = texture2DRect(NormalWeight, gl_FragCoord.st + epsilon); normaldepth.xyz = normaldepth.xyz/normaldepth.w; #if (EXPE_OUTPUT_DEPTH==1) gl_FragDepth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; #endif #if EXPE_DEPTH_INTERPOLATION==2 float depth = -normaldepth.z; #elif EXPE_DEPTH_INTERPOLATION==1 float depth = unproj.y/(2.0*normaldepth.z+unproj.x-1.0); #else float depth = texture2DRect(Depth, gl_FragCoord.st + epsilon).x; depth = unproj.y/(2.0*depth+unproj.x-1.0); #endif vec3 normal = normaldepth.xyz; #if EXPE_DEPTH_INTERPOLATION!=0 normal.z = sqrt(1. - dot(vec3(normal.xy,0),vec3(normal.xy,0))); #endif normal = normalize(normal); vec3 eyePos = gl_TexCoord[0].xyz * depth; gl_FragColor = meshlabLighting(color, eyePos, normal); gl_FragColor.a = 1.0; } #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/splatting_apss/shaders/Raycasting.glsl0000644000175000017500000002443511517500604025361 0ustar gladkgladk/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * 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. * * * ****************************************************************************/ // #version 110 // #extension all : enable #pragma optimize(on) #ifndef EXPE_EWA_HINT #define EXPE_EWA_HINT 0 #endif #ifndef EXPE_DEPTH_INTERPOLATION #define EXPE_DEPTH_INTERPOLATION 0 #endif //-------------------------------------------------------------------------------- // shared variables //-------------------------------------------------------------------------------- // custom vertex attributes //attribute float radius; #ifdef CLIPPED_SPLAT attribute vec3 secondNormal; varying vec4 clipLine; #endif // standard uniforms uniform float expeRadiusScale; uniform float expePreComputeRadius; uniform float expeDepthOffset; // varying varying vec4 covmat; varying vec3 fragNormal; varying vec3 fragNoverCdotN; varying vec3 fragCenter; varying float scaleSquaredDistance; #ifdef EXPE_ATI_WORKAROUND varying vec4 fragCenterAndRadius; #endif #ifdef EXPE_DEPTH_CORRECTION varying float depthOffset; #endif uniform vec2 halfVp; uniform float oneOverEwaRadius; #ifdef EXPE_BACKFACE_SHADING #undef EXPE_EARLY_BACK_FACE_CULLING //#define EXPE_EWA_HINT 2 #endif //-------------------------------------------------------------------------------- // Visibility Splatting // Vertex Shader //-------------------------------------------------------------------------------- #ifdef __VisibilityVP__ varying vec2 scaledFragCenter2d; void VisibilityVP(void) { vec3 normal = normalize(gl_NormalMatrix * gl_Normal); // Point in eye space vec4 ePos = gl_ModelViewMatrix * gl_Vertex; float dotpn = dot(normal.xyz,ePos.xyz); vec4 oPos; #ifdef EXPE_EARLY_BACK_FACE_CULLING // back_face culling oPos = vec4(0,0,1,0); if(dotpn<0.) { #endif float radius = gl_MultiTexCoord2.x * expeRadiusScale; vec4 pointSize; pointSize.x = radius * expePreComputeRadius / ePos.z; gl_PointSize = max(1.0, pointSize.x); scaleSquaredDistance = 1.0 / (radius * radius); //fragNormal = normal; fragCenter = ePos.xyz; fragNoverCdotN = normal/dot(ePos.xyz,normal); #ifndef EXPE_DEPTH_CORRECTION ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; #else //ePos.xyz += normalize(ePos.xyz) * expeDepthOffset * radius; depthOffset = expeDepthOffset * radius; #endif oPos = gl_ProjectionMatrix * ePos; #if (EXPE_EWA_HINT>0) scaledFragCenter2d = 0.5*((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; #endif #ifdef EXPE_ATI_WORKAROUND fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; fragCenterAndRadius.w = pointSize.x; #endif #ifndef EXPE_EARLY_BACK_FACE_CULLING oPos.w = oPos.w * ( (dotpn<0.0) ? 1.0 : 0.0); #else } #endif gl_Position = oPos; } #endif //-------------------------------------------------------------------------------- // Visibility Splatting // Fragment Shader //-------------------------------------------------------------------------------- #ifdef __VisibilityFP__ varying vec2 scaledFragCenter2d; uniform vec3 rayCastParameter1; uniform vec3 rayCastParameter2; uniform vec2 depthParameterCast; void VisibilityFP(void) { #ifdef EXPE_ATI_WORKAROUND vec3 fragCoord; fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; fragCoord.z = fragCenterAndRadius.z; #else vec3 fragCoord = gl_FragCoord.xyz; #endif // compute q in object space vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; // MAD float oneOverDepth = dot(qOne,-fragNoverCdotN); // DP3 float depth = (1.0/oneOverDepth); // RCP vec3 diff = fragCenter + qOne * depth; // MAD float r2 = dot(diff,diff); // DP3 #if (EXPE_EWA_HINT>0) vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; // MAD float r2d = dot(d2,d2); // DP3 gl_FragColor = vec4(min(r2d,r2*scaleSquaredDistance)); #else gl_FragColor = vec4(r2*scaleSquaredDistance); #endif #ifdef EXPE_DEPTH_CORRECTION oneOverDepth = 1.0/(-depth+depthOffset); gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; // MAD #endif } #endif #ifdef __AttributeVP__ varying vec2 scaledFragCenter2d; void AttributeVP(void) { // transform normal vec3 normal = normalize(gl_NormalMatrix * gl_Normal); // Point in eye space vec4 ePos = gl_ModelViewMatrix * gl_Vertex; float dotpn = dot(normal.xyz,ePos.xyz); vec4 oPos; #ifdef EXPE_EARLY_BACK_FACE_CULLING // back_face culling oPos = vec4(0,0,1,0); if(dotpn<0.) { #endif #ifdef EXPE_BACKFACE_SHADING if(dotpn>0.) { dotpn = -dotpn; normal = -normal; } #endif float radius = gl_MultiTexCoord2.x * expeRadiusScale * 1.05; vec4 pointSize; pointSize.x = radius * expePreComputeRadius / ePos.z; #if (EXPE_EWA_HINT>0) gl_PointSize = max(2.0, pointSize.x); #else gl_PointSize = max(1.0, pointSize.x); #endif scaleSquaredDistance = 1. / (radius * radius); ///********* uncommented fragNormal.... //fragNormal = normal; fragCenter = ePos.xyz; fragNoverCdotN = normal/dot(ePos.xyz,normal); // Output color #ifdef EXPE_DEFERRED_SHADING fragNormal.xyz = normal.xyz; gl_FrontColor = gl_Color; #else // Output color #ifdef EXPE_LIGHTING gl_FrontColor = expeLighting(gl_Color, ePos.xyz, normal.xyz, 1.); #else gl_FrontColor = meshlabLighting(gl_Color, ePos.xyz, normal.xyz); #endif #endif oPos = gl_ModelViewProjectionMatrix * gl_Vertex; #ifdef EXPE_ATI_WORKAROUND fragCenterAndRadius.xyz = (oPos.xyz/oPos.w) + 1.0; fragCenterAndRadius.xy = fragCenterAndRadius.xy*halfVp; fragCenterAndRadius.z = fragCenterAndRadius.z*0.5; fragCenterAndRadius.w = pointSize.x; #endif #if (EXPE_EWA_HINT>0) scaledFragCenter2d = ((oPos.xy/oPos.w)+1.0)*halfVp*oneOverEwaRadius; #endif #ifndef EXPE_EARLY_BACK_FACE_CULLING oPos.w = oPos.w * (dotpn<0. ? 1.0 : 0.0); #else } #endif gl_Position = oPos; } #endif //-------------------------------------------------------------------------------- // EWA Splatting // Fragment Shader //-------------------------------------------------------------------------------- #ifdef __AttributeFP__ // this sampler is only used by this fragment shader varying vec2 scaledFragCenter2d; uniform vec3 rayCastParameter1; uniform vec3 rayCastParameter2; uniform vec2 depthParameterCast; // uniform sampler1D Kernel1dMap; void AttributeFP(void) { #ifdef EXPE_ATI_WORKAROUND vec3 fragCoord; fragCoord.xy = fragCenterAndRadius.xy + (gl_TexCoord[0].st-0.5) * fragCenterAndRadius.w; fragCoord.z = fragCenterAndRadius.z; #else vec3 fragCoord = gl_FragCoord.xyz; #endif #if 1 vec3 qOne = rayCastParameter1 * fragCoord + rayCastParameter2; // MAD float oneOverDepth = dot(qOne,fragNoverCdotN); // DP3 float depth = (1.0/oneOverDepth); // RCP vec3 diff = fragCenter - qOne * depth; // MAD float r2 = dot(diff,diff); // DP3 #if (EXPE_EWA_HINT>0) vec2 d2 = oneOverEwaRadius*gl_FragCoord.xy - scaledFragCenter2d; // MAD float r2d = dot(d2,d2); // DP3 // float weight = texture1D(Kernel1dMap, min(r2d,r2*scaleSquaredDistance)).a; // MUL + MIN + TEX float weight = min(r2d,r2*scaleSquaredDistance); weight = clamp(1.-weight,0,1); weight = weight*weight; #else //float weight = texture1D(Kernel1dMap, r2*scaleSquaredDistance).a; // MUL + TEX float weight = clamp(1.-r2*scaleSquaredDistance,0.0,1.0); weight = weight*weight; #endif weight *= 0.1; // limits overflow #ifdef EXPE_DEPTH_CORRECTION gl_FragDepth = depthParameterCast.x * oneOverDepth + depthParameterCast.y; // MAD #endif #ifdef EXPE_DEFERRED_SHADING gl_FragData[0].rgb = gl_Color.rgb; // MOV gl_FragData[1].xyz = fragNormal.xyz; // MOV gl_FragData[1].w = weight; // MOV gl_FragData[0].w = weight; #if EXPE_DEPTH_INTERPOLATION==2 // linear space gl_FragData[1].z = -depth; // MOV #elif EXPE_DEPTH_INTERPOLATION==1 // window space #ifdef EXPE_DEPTH_CORRECTION gl_FragData[1].z = gl_FragDepth; #else gl_FragData[1].z = fragCoord.z; #endif #endif #else gl_FragColor.rgb = gl_Color.rgb; // MOV gl_FragColor.w = weight; #endif #endif } #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/splatting_apss/splatrenderer.h0000644000175000017500000006344011551320500023754 0ustar gladkgladk/**************************************************************************** * MeshLab o o * * A versatile mesh processing toolbox o o * * _ O _ * * Copyright(C) 2005 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef SPLATRENDERER_H #define SPLATRENDERER_H #include #include #include #include #include #include #include #include #define GL_TEST_ERR\ {\ GLenum eCode;\ if((eCode=glGetError())!=GL_NO_ERROR)\ std::cerr << "OpenGL error : " << gluErrorString(eCode) << " in " << __FILE__ << " : " << __LINE__ << std::endl;\ } class QGLFramebufferObject; /* Rendering with Algebraic Point Set Surfaces, by Gael Guennebaud. paper: Algebraic Point Set Surfaces SIGGRAPH '07 */ template class SplatRenderer { bool mIsSupported; bool init_called; enum { DEFERRED_SHADING_BIT = 0x000001, DEPTH_CORRECTION_BIT = 0x000002, OUTPUT_DEPTH_BIT = 0x000004, BACKFACE_SHADING_BIT = 0x000008, FLOAT_BUFFER_BIT = 0x000010 }; int mFlags; int mCachedFlags; int mRenderBufferMask; int mSupportedMask; //int mCurrentPass; int mBindedPass; GLuint mDummyTexId; // on ATI graphics card we need to bind a texture to get point sprite working ! bool mWorkaroundATI; bool mBuggedAtiBlending; GLuint mNormalTextureID; GLuint mDepthTextureID; ProgramVF mShaders[3]; QString mShaderSrcs[6]; QGLFramebufferObject* mRenderBuffer; float mCachedMV[16]; float mCachedProj[16]; GLint mCachedVP[4]; struct UniformParameters { float radiusScale; float preComputeRadius; float depthOffset; float oneOverEwaRadius; vcg::Point2f halfVp; vcg::Point3f rayCastParameter1; vcg::Point3f rayCastParameter2; vcg::Point2f depthParameterCast; void loadTo(Program& prg); void update(float* mv, float* proj, GLint* vp); }; UniformParameters mParams; QString loadSource(const QString& func,const QString& file); void configureShaders(); void updateRenderBuffer(); void enablePass(int n); void drawSplats(std::vector & , vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm); void drawSplats( std::vector< std::vector * > & positions, std::vector< std::vector * > & normals, std::vector< std::vector > * > & colors, std::vector & radius, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm); public: void Clear(); void Destroy(); bool isSupported() {return mIsSupported;} void Init(QGLWidget *gla); void Render( std::vector &meshes, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm); void Render( std::vector< std::vector * > & positions, std::vector< std::vector * > & normals, std::vector< std::vector > * > & colors, std::vector & radius, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm); };// end class template void SplatRenderer:: Destroy(){ delete mRenderBuffer; mRenderBuffer = 0; glDeleteTextures(1,&mDepthTextureID); glDeleteTextures(1,&mNormalTextureID); for(int i = 0; i < 3; ++i) this->mShaders[i].prog.Del(); Clear(); } template void SplatRenderer::Clear() { mNormalTextureID = 0; mDepthTextureID = 0; mIsSupported = false; mRenderBuffer = 0; mWorkaroundATI = false; mBuggedAtiBlending = false; mDummyTexId = 0; mFlags = DEFERRED_SHADING_BIT | DEPTH_CORRECTION_BIT | FLOAT_BUFFER_BIT | OUTPUT_DEPTH_BIT; mCachedFlags = ~mFlags; // union of bits which controls the render buffer mRenderBufferMask = DEFERRED_SHADING_BIT | FLOAT_BUFFER_BIT; init_called = false; } template QString SplatRenderer::loadSource(const QString& func,const QString& filename) { QString res; QFile f(":/SplatRenderer/shaders/" + filename); if (!f.open(QFile::ReadOnly)) { std::cerr << "failed to load shader file " << filename.toAscii().data() << "\n"; return res; } else qDebug("Succesfully loaded shader func '%s' in file '%s'",qPrintable(func),qPrintable(filename)); QTextStream stream(&f); res = stream.readAll(); f.close(); res = QString("#define __%1__ 1\n").arg(func) + QString("#define %1 main\n").arg(func) + res; return res; } template void SplatRenderer::configureShaders() { const char* passNames[3] = {"Visibility","Attribute","Finalization"}; QString defines = ""; if (mFlags & DEFERRED_SHADING_BIT) defines += "#define EXPE_DEFERRED_SHADING\n"; if (mFlags & DEPTH_CORRECTION_BIT) defines += "#define EXPE_DEPTH_CORRECTION\n"; if (mFlags & OUTPUT_DEPTH_BIT) defines += "#define EXPE_OUTPUT_DEPTH 1\n"; if (mFlags & BACKFACE_SHADING_BIT) defines += "#define EXPE_BACKFACE_SHADING\n"; if (mWorkaroundATI) defines += "#define EXPE_ATI_WORKAROUND\n"; QString shading = "vec4 meshlabLighting(vec4 color, vec3 eyePos, vec3 normal)" "{" " normal = normalize(normal);" " vec3 lightVec = normalize(gl_LightSource[0].position.xyz);" " vec3 halfVec = normalize( lightVec - normalize(eyePos) );" " float aux_dot = dot(normal,lightVec);" " float diffuseCoeff = clamp(aux_dot, 0.0, 1.0);" " float specularCoeff = aux_dot>0.0 ? clamp(pow(clamp(dot(halfVec, normal),0.0,1.0),gl_FrontMaterial.shininess), 0.0, 1.0) : 0.0;" " return vec4(color.rgb * ( gl_FrontLightProduct[0].ambient.rgb + diffuseCoeff * gl_FrontLightProduct[0].diffuse.rgb) + specularCoeff * gl_FrontLightProduct[0].specular.rgb, 1.0);" "}\n"; for (int k=0;k<3;++k) { QString vsrc = shading + defines + mShaderSrcs[k*2+0]; QString fsrc = shading + defines + mShaderSrcs[k*2+1]; mShaders[k].SetSources(mShaderSrcs[k*2+0]!="" ? vsrc.toAscii().data() : 0, mShaderSrcs[k*2+1]!="" ? fsrc.toAscii().data() : 0); mShaders[k].prog.Link(); if (mShaderSrcs[k*2+0]!="") { std::string compileinfo = mShaders[k].vshd.InfoLog(); if (compileinfo.size()>0) std::cout << "Vertex shader info (" << passNames[k] << ":\n" << compileinfo << "\n"; } if (mShaderSrcs[k*2+1]!="") { std::string compileinfo = mShaders[k].fshd.InfoLog(); if (compileinfo.size()>0) std::cout << "Fragment shader info (" << passNames[k] << ":\n" << compileinfo << "\n"; } std::string linkinfo = mShaders[k].prog.InfoLog(); if (linkinfo.size()>0) std::cout << "Link info (" << passNames[k] << ":\n" << linkinfo << "\n"; } } template void SplatRenderer::Init(QGLWidget *gla) { mIsSupported = true; gla->makeCurrent(); // FIXME this should be done in meshlab !!! ?? glewInit(); const char* rs = (const char*)glGetString(GL_RENDERER); QString rendererString(""); if(rs) rendererString = QString(rs); mWorkaroundATI = rendererString.startsWith("ATI") || rendererString.startsWith("AMD"); // FIXME: maybe some recent HW correctly supports floating point blending... mBuggedAtiBlending = rendererString.startsWith("ATI") || rendererString.startsWith("AMD"); if (mWorkaroundATI && mDummyTexId==0) { glActiveTexture(GL_TEXTURE0); glGenTextures(1,&mDummyTexId); glBindTexture(GL_TEXTURE_2D, mDummyTexId); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); } // let's check the GPU capabilities mSupportedMask = DEPTH_CORRECTION_BIT | BACKFACE_SHADING_BIT; if (!QGLFramebufferObject::hasOpenGLFramebufferObjects ()) { mIsSupported = false; return; } if (GLEW_ARB_texture_float) mSupportedMask |= FLOAT_BUFFER_BIT; else std::cout << "Splatting: warning floating point textures are not supported.\n"; if (GLEW_ARB_draw_buffers && (!mBuggedAtiBlending)) mSupportedMask |= DEFERRED_SHADING_BIT; else std::cout << "Splatting: warning deferred shading is not supported.\n"; if (GLEW_ARB_shadow) mSupportedMask |= OUTPUT_DEPTH_BIT; else std::cerr << "Splatting: warning copy of the depth buffer is not supported.\n"; mFlags = mFlags & mSupportedMask; // load shader source mShaderSrcs[0] = loadSource("VisibilityVP","Raycasting.glsl"); mShaderSrcs[1] = loadSource("VisibilityFP","Raycasting.glsl"); mShaderSrcs[2] = loadSource("AttributeVP","Raycasting.glsl"); mShaderSrcs[3] = loadSource("AttributeFP","Raycasting.glsl"); mShaderSrcs[4] = ""; mShaderSrcs[5] = loadSource("Finalization","Finalization.glsl"); //mCurrentPass = 2; mBindedPass = -1; GL_TEST_ERR } template void SplatRenderer::updateRenderBuffer() { if ( (!mRenderBuffer) || (mRenderBuffer->width()!=mCachedVP[2]) || (mRenderBuffer->height()!=mCachedVP[3]) || ( (mCachedFlags & mRenderBufferMask) != (mFlags & mRenderBufferMask) )) { delete mRenderBuffer; GLenum fmt = (mFlags&FLOAT_BUFFER_BIT) ? GL_RGBA16F_ARB : GL_RGBA; mRenderBuffer = new QGLFramebufferObject(mCachedVP[2], mCachedVP[3], (mFlags&OUTPUT_DEPTH_BIT) ? QGLFramebufferObject::NoAttachment : QGLFramebufferObject::Depth, GL_TEXTURE_RECTANGLE_ARB, fmt); if (!mRenderBuffer->isValid()) { std::cout << "SplatRenderer: invalid FBO\n"; } GL_TEST_ERR if (mFlags&DEFERRED_SHADING_BIT) { // in deferred shading mode we need an additional buffer to accumulate the normals if (mNormalTextureID==0) glGenTextures(1,&mNormalTextureID); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, fmt, mCachedVP[2], mCachedVP[3], 0, GL_RGBA, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mRenderBuffer->bind(); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_ARB, mNormalTextureID, 0); mRenderBuffer->release(); GL_TEST_ERR } if (mFlags&OUTPUT_DEPTH_BIT) { // to output the depth values to the final depth buffer we need to // attach a depth buffer as a texture if (mDepthTextureID==0) glGenTextures(1,&mDepthTextureID); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_DEPTH_COMPONENT24_ARB, mCachedVP[2], mCachedVP[3], 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); mRenderBuffer->bind(); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_ARB, mDepthTextureID, 0); mRenderBuffer->release(); GL_TEST_ERR } } } template void SplatRenderer::Render(std::vector & meshes, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm ) { if(meshes.empty()) return; GL_TEST_ERR /*************** First Pass ***********/ // this is the first pass of the frame, so let's update the shaders, buffers, etc... glGetIntegerv(GL_VIEWPORT, mCachedVP); glGetFloatv(GL_MODELVIEW_MATRIX, mCachedMV); glGetFloatv(GL_PROJECTION_MATRIX, mCachedProj); updateRenderBuffer(); if (mCachedFlags != mFlags) configureShaders(); mCachedFlags = mFlags; mParams.update(mCachedMV, mCachedProj, mCachedVP); //float s = meshes[0]->glw.GetHintParamf(vcg::GLW::HNPPointSize); //if (s>1) // s = pow(s,0.3f); float s = 1.f; mParams.radiusScale *= s; // FIXME since meshlab does not set any material properties, let's define some here glDisable(GL_COLOR_MATERIAL); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, vcg::Point4f(0.3, 0.3, 0.3, 1.).V()); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, vcg::Point4f(0.6, 0.6, 0.6, 1.).V()); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, vcg::Point4f(0.5, 0.5, 0.5, 1.).V()); mRenderBuffer->bind(); if (mFlags&DEFERRED_SHADING_BIT) { GLenum buf[2] = {GL_COLOR_ATTACHMENT0_EXT,GL_COLOR_ATTACHMENT1_EXT}; glDrawBuffersARB(2, buf); } glViewport(mCachedVP[0],mCachedVP[1],mCachedVP[2],mCachedVP[3]); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //* End Setup of first Pass Now a simple rendering of all the involved meshes.*/ mParams.loadTo(mShaders[0].prog); enablePass(0); drawSplats(meshes,cm,tm); // begin second pass mParams.loadTo(mShaders[1].prog); enablePass(1); drawSplats(meshes,cm,tm); //* Start third Pass Setup */ // this is the last pass: normalization by the sum of weights + deferred shading mRenderBuffer->release(); if (mFlags&DEFERRED_SHADING_BIT) glDrawBuffer(GL_BACK); enablePass(2); // switch to normalized 2D rendering mode glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); mShaders[2].prog.Uniform("viewport",float(mCachedVP[0]),float(mCachedVP[1]),float(mCachedVP[2]),float(mCachedVP[3])); mShaders[2].prog.Uniform("ColorWeight",GLint(0)); // this is a texture unit glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mRenderBuffer->texture()); if (mFlags&DEFERRED_SHADING_BIT) { mShaders[2].prog.Uniform("unproj", mCachedProj[10], mCachedProj[14]); mShaders[2].prog.Uniform("NormalWeight",GLint(1)); // this is a texture unit glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mNormalTextureID); GL_TEST_ERR } if (mFlags&OUTPUT_DEPTH_BIT) { mShaders[2].prog.Uniform("Depth",GLint(2)); // this is a texture unit glActiveTexture(GL_TEXTURE2);GL_TEST_ERR glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mDepthTextureID);GL_TEST_ERR GL_TEST_ERR } else { glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); } // draw a quad covering the whole screen vcg::Point3f viewVec(1./mCachedProj[0], 1./mCachedProj[5], -1); glBegin(GL_QUADS); glColor3f(1, 0, 0); glTexCoord3f(viewVec.X(),viewVec.Y(),viewVec.Z()); glMultiTexCoord2f(GL_TEXTURE1,1.,1.); glVertex3f(1,1,0); glColor3f(1, 1, 0); glTexCoord3f(-viewVec.X(),viewVec.Y(),viewVec.Z()); glMultiTexCoord2f(GL_TEXTURE1,0.,1.); glVertex3f(-1,1,0); glColor3f(0, 1, 1); glTexCoord3f(-viewVec.X(),-viewVec.Y(),viewVec.Z()); glMultiTexCoord2f(GL_TEXTURE1,0.,0.); glVertex3f(-1,-1,0); glColor3f(1, 0, 1); glTexCoord3f(viewVec.X(),-viewVec.Y(),viewVec.Z()); glMultiTexCoord2f(GL_TEXTURE1,1.,0.); glVertex3f(1,-1,0); glEnd(); if (!(mFlags&OUTPUT_DEPTH_BIT)) { glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); } glUseProgram(0); // restore matrices glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); GL_TEST_ERR } template void SplatRenderer::Render( std::vector< std::vector * > & positions, std::vector< std::vector * > & normals, std::vector< std::vector > * > & colors, std::vector & radius, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm ) { if(positions.empty()) return; GL_TEST_ERR /*************** First Pass ***********/ // this is the first pass of the frame, so let's update the shaders, buffers, etc... glGetIntegerv(GL_VIEWPORT, mCachedVP); glGetFloatv(GL_MODELVIEW_MATRIX, mCachedMV); glGetFloatv(GL_PROJECTION_MATRIX, mCachedProj); updateRenderBuffer(); if (mCachedFlags != mFlags) configureShaders(); mCachedFlags = mFlags; mParams.update(mCachedMV, mCachedProj, mCachedVP); //float s = meshes[0]->glw.GetHintParamf(vcg::GLW::HNPPointSize); //if (s>1) // s = pow(s,0.3f); float s = 1.f; mParams.radiusScale *= s; // FIXME since meshlab does not set any material properties, let's define some here glDisable(GL_COLOR_MATERIAL); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, vcg::Point4f(0.3, 0.3, 0.3, 1.).V()); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, vcg::Point4f(0.6, 0.6, 0.6, 1.).V()); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, vcg::Point4f(0.5, 0.5, 0.5, 1.).V()); mRenderBuffer->bind(); if (mFlags&DEFERRED_SHADING_BIT) { GLenum buf[2] = {GL_COLOR_ATTACHMENT0_EXT,GL_COLOR_ATTACHMENT1_EXT}; glDrawBuffersARB(2, buf); } glViewport(mCachedVP[0],mCachedVP[1],mCachedVP[2],mCachedVP[3]); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //* End Setup of first Pass Now a simple rendering of all the involved meshes.*/ mParams.loadTo(mShaders[0].prog); enablePass(0); drawSplats(positions,normals,colors,radius,cm,tm); // begin second pass mParams.loadTo(mShaders[1].prog); enablePass(1); drawSplats(positions,normals,colors,radius,cm,tm); //* Start third Pass Setup */ // this is the last pass: normalization by the sum of weights + deferred shading mRenderBuffer->release(); if (mFlags&DEFERRED_SHADING_BIT) glDrawBuffer(GL_BACK); enablePass(2); // switch to normalized 2D rendering mode glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); mShaders[2].prog.Uniform("viewport",float(mCachedVP[0]),float(mCachedVP[1]),float(mCachedVP[2]),float(mCachedVP[3])); mShaders[2].prog.Uniform("ColorWeight",GLint(0)); // this is a texture unit glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mRenderBuffer->texture()); if (mFlags&DEFERRED_SHADING_BIT) { mShaders[2].prog.Uniform("unproj", mCachedProj[10], mCachedProj[14]); mShaders[2].prog.Uniform("NormalWeight",GLint(1)); // this is a texture unit glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mNormalTextureID); GL_TEST_ERR } if (mFlags&OUTPUT_DEPTH_BIT) { mShaders[2].prog.Uniform("Depth",GLint(2)); // this is a texture unit glActiveTexture(GL_TEXTURE2);GL_TEST_ERR glBindTexture(GL_TEXTURE_RECTANGLE_ARB,mDepthTextureID);GL_TEST_ERR GL_TEST_ERR } else { glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); } // draw a quad covering the whole screen vcg::Point3f viewVec(1./mCachedProj[0], 1./mCachedProj[5], -1); glBegin(GL_QUADS); glColor3f(1, 0, 0); glTexCoord3f(viewVec.X(),viewVec.Y(),viewVec.Z()); glMultiTexCoord2f(GL_TEXTURE1,1.,1.); glVertex3f(1,1,0); glColor3f(1, 1, 0); glTexCoord3f(-viewVec.X(),viewVec.Y(),viewVec.Z()); glMultiTexCoord2f(GL_TEXTURE1,0.,1.); glVertex3f(-1,1,0); glColor3f(0, 1, 1); glTexCoord3f(-viewVec.X(),-viewVec.Y(),viewVec.Z()); glMultiTexCoord2f(GL_TEXTURE1,0.,0.); glVertex3f(-1,-1,0); glColor3f(1, 0, 1); glTexCoord3f(viewVec.X(),-viewVec.Y(),viewVec.Z()); glMultiTexCoord2f(GL_TEXTURE1,1.,0.); glVertex3f(1,-1,0); glEnd(); if (!(mFlags&OUTPUT_DEPTH_BIT)) { glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); } glUseProgram(0); // restore matrices glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); GL_TEST_ERR } #if 0 void SplatRenderer::Draw(QAction *a, MeshModel &m, RenderMode &rm, QGLWidget * gla) { if (m.vert.RadiusEnabled) { if (mCurrentPass==2) return; enablePass(mCurrentPass); /*if (mCurrentPass==1)*/ drawSplats(m, rm); } else if (mCurrentPass==2) { MeshRenderInterface::Draw(a, m, rm, gla); } } #endif template void SplatRenderer::enablePass(int n) { if (mBindedPass!=n) { if (mBindedPass>=0) mShaders[mBindedPass].prog.Unbind(); mShaders[n].prog.Bind(); mBindedPass = n; // set GL states if (n==0) { glDisable(GL_LIGHTING); // glDisable(GL_POINT_SMOOTH); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glAlphaFunc(GL_LESS,1); glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); glDepthMask(GL_TRUE); glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); glEnable(GL_DEPTH_TEST); // glActiveTexture(GL_TEXTURE0); // glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); // glEnable(GL_POINT_SPRITE_ARB); } if (n==1) { glDisable(GL_LIGHTING); glEnable(GL_POINT_SMOOTH); glActiveTexture(GL_TEXTURE0); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE,GL_ONE); // //glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE,GL_ZERO); // glBlendFunc(GL_ONE,GL_ZERO); glDepthMask(GL_FALSE); glEnable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDisable(GL_ALPHA_TEST); // glActiveTexture(GL_TEXTURE0); } if ( (n==0) || (n==1) ) { // enable point sprite rendering mode glActiveTexture(GL_TEXTURE0); if (mWorkaroundATI) { glBindTexture(GL_TEXTURE_2D, mDummyTexId); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); glPointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); // hm... ^^^^ } glTexEnvf(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); glEnable(GL_POINT_SPRITE_ARB); } if (n==2) { glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glDepthMask(GL_TRUE); glDisable(GL_LIGHTING); glDisable(GL_BLEND); } } } template void SplatRenderer::drawSplats( std::vector< std::vector * > & positions, std::vector< std::vector * > & normals, std::vector< std::vector > * > & colors, std::vector & radius, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm) { for(unsigned int ii = 0; ii < positions.size();++ii) { glBegin(GL_POINTS); glMultiTexCoord1f(GL_TEXTURE2, radius[ii] ); for(unsigned int vi= 0;vi< positions[ii]->size() ;++vi){ vcg::Point3 co = (*colors[ii])[vi]; glColor3ub ( co[0],co[1],co[2]); glNormal((*normals[ii])[vi]); glVertex( (*positions[ii])[vi]); } glEnd(); } } template void SplatRenderer::drawSplats(std::vector & meshes, vcg::GLW::ColorMode cm, vcg::GLW::TextureMode tm) { // check if we have to use the immediate mode if(meshes.empty()) return; int nV = 0; /* temporary patch: If the number of vertices is above IMMEDIATE_MODE_THR, use the immediate mode */ const int IMMEDIATE_MODE_THR = 0; unsigned int ii = 0; for(; ii < meshes.size();++ii){ nV+=meshes[ii]->vn; if((nV>IMMEDIATE_MODE_THR) || (meshes[ii]->vn!=(int) meshes[ii]->vert.size())) break; } bool immediatemode = ii glw; glw.m = &m; glw.Draw(vcg::GLW::DMPoints,cm,tm); glClientActiveTexture(GL_TEXTURE2); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(GL_TEXTURE0); } } template void SplatRenderer::UniformParameters::update(float* mv, float* proj, GLint* vp) { // extract the uniform scale float scale = vcg::Point3f(mv[0],mv[1],mv[2]).Norm(); radiusScale = scale; preComputeRadius = - std::max(proj[0]*vp[2], proj[5]*vp[3]); depthOffset = 2.0; oneOverEwaRadius = 0.70710678118654; halfVp = vcg::Point2f(0.5*vp[2], 0.5*vp[3]); rayCastParameter1 =vcg::Point3f(2./(proj[0]*vp[2]), 2./(proj[5]*vp[3]), 0.0); rayCastParameter2 =vcg::Point3f(-1./proj[0], -1./proj[5], -1.0); depthParameterCast = vcg::Point2f(0.5*proj[14], 0.5-0.5*proj[10]); } template void SplatRenderer ::UniformParameters::loadTo(Program& prg) { prg.Bind(); prg.Uniform("expeRadiusScale",radiusScale); prg.Uniform("expePreComputeRadius",preComputeRadius); prg.Uniform("expeDepthOffset",depthOffset); prg.Uniform("oneOverEwaRadius",oneOverEwaRadius); prg.Uniform("halfVp",halfVp); prg.Uniform("rayCastParameter1",rayCastParameter1); prg.Uniform("rayCastParameter2",rayCastParameter2); prg.Uniform("depthParameterCast",depthParameterCast); } #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/fbo.h0000644000175000017500000004326411517500604016626 0ustar gladkgladk/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef __FBO_H__ #define __FBO_H__ #pragma warning(disable : 4250) #include #include #include #include #include "gl_object.h" class FrameBufferSemantic { public: typedef enum { COLOR, DEPTH, STENCIL } FBSType; virtual FBSType Semantic(void) const = 0; virtual bool ValidateFormat(GLenum format) const = 0; static bool ValidateFormat(FBSType type, GLenum format) { switch (type) { case COLOR : return FrameBufferSemantic::ValidateColor(format); case DEPTH : return FrameBufferSemantic::ValidateDepth(format); case STENCIL : return FrameBufferSemantic::ValidateStencil(format); default : return false; } } static bool ValidateColor(GLenum type) { return true; } static bool ValidateDepth(GLenum type) { return true; } static bool ValidateStencil(GLenum type) { return true; } }; class Texture : public GLObject, public Bindable, public FrameBufferSemantic { public: Texture(void) : GLObject(), Bindable(), FrameBufferSemantic() { this->format = GL_NONE; } void Gen(void) { this->Del(); glGenTextures(1, &(this->objectID)); } void Del(void) { if (this->objectID == 0) return; glDeleteTextures(1, &(this->objectID)); this->objectID = 0; } GLenum Format(void) const { return this->format; } virtual GLint Dimensions(void) const = 0; virtual GLsizei Size(const unsigned int i) const = 0; virtual GLenum Target(void) const = 0; protected: GLenum format; void DoBind(void) { glBindTexture(this->Target(), this->objectID); } void DoUnbind(void) { glBindTexture(this->Target(), 0); } }; class ColorTexture : public virtual Texture { public: ColorTexture(void) : Texture() { } FrameBufferSemantic::FBSType Semantic(void) const { return FrameBufferSemantic::COLOR; } bool ValidateFormat(GLenum format) const { return FrameBufferSemantic::ValidateColor(format); } }; class DepthTexture : public virtual Texture { public: DepthTexture(void) : Texture() { } FrameBufferSemantic::FBSType Semantic(void) const { return FrameBufferSemantic::DEPTH; } bool ValidateFormat(GLenum format) const { return FrameBufferSemantic::ValidateDepth(format); } }; class StencilTexture : public virtual Texture { public: StencilTexture(void) : Texture() { } FrameBufferSemantic::FBSType Semantic(void) const { return FrameBufferSemantic::STENCIL; } bool ValidateFormat(GLenum format) const { return FrameBufferSemantic::ValidateStencil(format); } }; class Texture1D : public virtual Texture { public: Texture1D(void) : Texture() { this->dims[0] = 0; this->wraps[0] = GL_CLAMP_TO_EDGE; } GLsizei Width(void) const { return this->dims[0]; } GLint Dimensions(void) const { return 1; } GLsizei Size(const unsigned int i) const { if (i > 0) return 0; return this->dims[0]; } GLenum Target(void) const { return GL_TEXTURE_1D; } bool Set(GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels) { if (!this->ValidateFormat(internalFormat)) return false; this->Bind(); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage1D(GL_TEXTURE_1D, level, internalFormat, width, border, format, type, pixels); this->Unbind(); this->format = internalFormat; this->dims[0] = width; return true; } protected: GLsizei dims[1]; GLenum wraps[1]; }; class Texture2D : public virtual Texture { public: Texture2D(void) : Texture() { this->dims[0] = 0; this->dims[1] = 0; } GLsizei Width(void) const { return this->dims[0]; } GLsizei Height(void) const { return this->dims[1]; } GLint Dimensions(void) const { return 2; } GLsizei Size(const unsigned int i) const { if (i > 1) return 0; return this->dims[i]; } GLenum Target(void) const { return GL_TEXTURE_2D; } bool Set(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels) { if (!this->ValidateFormat(internalFormat)) return false; this->Bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, border, format, type, pixels); this->Unbind(); this->format = internalFormat; this->dims[0] = width; this->dims[1] = height; return true; } protected: GLsizei dims[2]; void DoBind(void) { glBindTexture(GL_TEXTURE_2D, this->objectID); } void DoUnbind(void) { glBindTexture(GL_TEXTURE_2D, 0); } }; class Texture3D : public virtual Texture { public: Texture3D(void) : Texture() { this->dims[0] = 0; this->dims[1] = 0; this->dims[2] = 0; } GLsizei Width(void) const { return this->dims[0]; } GLsizei Height(void) const { return this->dims[1]; } GLsizei Depth(void) const { return this->dims[2]; } GLint Dimensions(void) const { return 3; } GLsizei Size(const unsigned int i) const { if (i > 2) return 0; return this->dims[i]; } GLenum Target(void) const { return GL_TEXTURE_3D; } bool Set(GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels) { if (!this->ValidateFormat(internalFormat)) return false; this->Bind(); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage3D(GL_TEXTURE_3D, 0, internalFormat, width, height, depth, border, format, type, pixels); this->Unbind(); this->format = internalFormat; this->dims[0] = width; this->dims[1] = height; this->dims[2] = depth; return true; } protected: GLsizei dims[3]; void DoBind(void) { glBindTexture(GL_TEXTURE_3D, this->objectID); } void DoUnbind(void) { glBindTexture(GL_TEXTURE_3D, 0); } }; class ColorTexture1D : public virtual ColorTexture, public virtual Texture1D { public: ColorTexture1D(void) : ColorTexture(), Texture1D() { } }; class ColorTexture2D : public virtual ColorTexture, public virtual Texture2D { public: ColorTexture2D(void) : ColorTexture(), Texture2D() { } }; class ColorTexture3D : public virtual ColorTexture, public virtual Texture3D { public: ColorTexture3D(void) : ColorTexture(), Texture3D() { } }; class DepthTexture2D : public virtual DepthTexture, public virtual Texture2D { public: DepthTexture2D(void) : DepthTexture(), Texture2D() { } }; class StencilTexture2D : public virtual StencilTexture, public virtual Texture2D { public: StencilTexture2D(void) : StencilTexture(), Texture2D() { } }; class FrameBuffer; class RenderTarget : public GLObject, public Bindable, public FrameBufferSemantic { friend class FrameBuffer; public: typedef enum { BUFFER, TEXTURE } RTStorageType; RenderTarget(void) : GLObject(), Bindable(), FrameBufferSemantic() { this->frameBuffer = 0; } bool Attach(FrameBuffer * fb); bool Detach(void); FrameBuffer * GetFrameBuffer(void) { return this->frameBuffer; } const FrameBuffer * GetFrameBuffer(void) const { return this->frameBuffer; } virtual GLsizei Width(void) const = 0; virtual GLsizei Height(void) const = 0; virtual GLenum Format(void) const = 0; virtual GLenum Attachment(void) const = 0; virtual bool ValidateAttachment(GLenum attachment) const = 0; virtual RTStorageType StorageType(void) const = 0; protected: FrameBuffer * frameBuffer; virtual bool BindToFB(void) = 0; }; class BufferRenderTarget : public virtual RenderTarget { public: BufferRenderTarget(void) : RenderTarget() { this->width = 0; this->height = 0; this->format = GL_NONE; } void Gen(void) { this->Del(); glGenRenderbuffersEXT(1, &(this->objectID)); } void Del(void) { if (this->objectID == 0) return; glDeleteRenderbuffersEXT(1, &(this->objectID)); this->objectID = 0; } GLsizei Width(void) const { return this->width; } GLsizei Height(void) const { return this->height; } GLenum Format(void) const { return this->format; } RTStorageType StorageType(void) const { return RenderTarget::BUFFER; } bool Set(GLenum format, GLsizei width, GLsizei height) { if (!this->ValidateFormat(format)) return false; this->Bind(); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, width, height); this->Unbind(); this->format = format; this->width = width; this->height = height; return true; } bool BindToFB(void) { if (this->frameBuffer == 0) return false; glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, this->Attachment(), GL_RENDERBUFFER_EXT, this->objectID); return true; } protected: GLenum format; GLsizei width; GLsizei height; void DoBind(void) { glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, this->objectID); } void DoUnbind(void) { glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); } }; class TextureRenderTarget : public virtual RenderTarget { public: TextureRenderTarget(void) : RenderTarget() { this->tex = 0; this->level = 0; } void Gen(void) { } void Del(void) { } GLsizei Width(void) const { if (this->tex == 0) return 0; return this->tex->Width(); } GLsizei Height(void) const { if (this->tex == 0) return 0; return this->tex->Height(); } GLenum Format(void) const { if (this->tex == 0) return GL_NONE; return this->tex->Format(); } RTStorageType StorageType(void) const { return RenderTarget::TEXTURE; } void SetLevel(GLint level) { if (level < 0) level = 0; this->level = level; } bool Set(Texture2D * tex) { this->Unset(); if (tex == 0) return true; if (this->Semantic() != tex->Semantic()) return false; this->tex = tex; return true; } bool Unset(void) { this->tex = 0; return true; } Texture2D * GetTexture(void) { return (this->tex); } bool BindToFB(void) { if (this->frameBuffer == 0) return false; if (this->tex == 0) return false; glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, this->Attachment(), GL_TEXTURE_2D, this->tex->ObjectID(), this->level); return true; } protected: Texture2D * tex; GLint level; void DoBind(void) { } void DoUnbind(void) { } }; class ColorRenderTarget : public virtual RenderTarget { public: ColorRenderTarget(void) : RenderTarget() { this->attachment = GL_COLOR_ATTACHMENT0_EXT; } FrameBufferSemantic::FBSType Semantic(void) const { return FrameBufferSemantic::COLOR; } bool ValidateFormat(GLenum format) const { return FrameBufferSemantic::ValidateColor(format); } bool ValidateAttachment(GLenum attachment) const { return (((GL_COLOR_ATTACHMENT0_EXT) <= attachment) && (attachment <= (GL_COLOR_ATTACHMENT0_EXT + 3))); } void SetAttachment(GLenum attachment) { if (!this->ValidateAttachment(attachment)) return; this->attachment = attachment; } GLenum Attachment(void) const { return this->attachment; } protected: GLenum attachment; }; class DepthRenderTarget : public virtual RenderTarget { public: DepthRenderTarget(void) : RenderTarget() { } FrameBufferSemantic::FBSType Semantic(void) const { return FrameBufferSemantic::DEPTH; } bool ValidateFormat(GLenum format) const { return FrameBufferSemantic::ValidateDepth(format); } bool ValidateAttachment(GLenum attachment) const { return (attachment == GL_DEPTH_ATTACHMENT_EXT); } GLenum Attachment(void) const { return GL_DEPTH_ATTACHMENT_EXT; } }; class StencilRenderTarget : public virtual RenderTarget { public: StencilRenderTarget(void) : RenderTarget() { } FrameBufferSemantic::FBSType Semantic(void) const { return FrameBufferSemantic::STENCIL; } bool ValidateFormat(GLenum format) const { return FrameBufferSemantic::ValidateStencil(format); } bool ValidateAttachment(GLenum attachment) const { return (attachment == GL_STENCIL_ATTACHMENT_EXT); } GLenum Attachment(void) const { return GL_STENCIL_ATTACHMENT_EXT; } }; class ColorRenderBuffer : public virtual ColorRenderTarget, public virtual BufferRenderTarget { public: ColorRenderBuffer(void) : ColorRenderTarget(), BufferRenderTarget() { } }; class ColorRenderTexture : public virtual ColorRenderTarget, public virtual TextureRenderTarget { public: ColorRenderTexture(void) : ColorRenderTarget(), TextureRenderTarget() { } ColorRenderTexture(Texture2D * tex) : ColorRenderTarget(), TextureRenderTarget() { this->Set(tex); } }; class DepthRenderBuffer : public virtual DepthRenderTarget, public virtual BufferRenderTarget { public: DepthRenderBuffer(void) : DepthRenderTarget(), BufferRenderTarget() { } }; class DepthRenderTexture : public virtual DepthRenderTarget, public virtual TextureRenderTarget { public: DepthRenderTexture(void) : DepthRenderTarget(), TextureRenderTarget() { } DepthRenderTexture(Texture2D * tex) : DepthRenderTarget(), TextureRenderTarget() { this->Set(tex); } }; class StencilRenderBuffer : public virtual StencilRenderTarget, public virtual BufferRenderTarget { public: StencilRenderBuffer(void) : StencilRenderTarget(), BufferRenderTarget() { } }; class StencilRenderTexture : public virtual StencilRenderTarget, public virtual TextureRenderTarget { public: StencilRenderTexture(void) : StencilRenderTarget(), TextureRenderTarget() { } StencilRenderTexture(Texture2D * tex) : StencilRenderTarget(), TextureRenderTarget() { this->Set(tex); } }; class FrameBuffer : public GLObject, public Bindable { friend class RenderTarget; public: FrameBuffer(void) : GLObject(), Bindable() { } void Gen(void) { this->Del(); glGenFramebuffersEXT(1, &(this->objectID)); } void Del(void) { if (this->objectID == 0) return; glDeleteFramebuffersEXT(1, &(this->objectID)); this->objectID = 0; } bool DetachAll(void) { return false; } bool IsValid(void) const { const GLenum s = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); //return (s == GL_FRAMEBUFFER_COMPLETE_EXT); switch (s) { case GL_FRAMEBUFFER_COMPLETE_EXT: printf("ok\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: printf("i a\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: printf("i m a\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: printf("i d a\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: printf("i d\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: printf("i f\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: printf("i d b\n"); break; case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: printf("i r b\n"); break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: printf("u\n"); break; default: printf("def\n"); break; } return (s == GL_FRAMEBUFFER_COMPLETE_EXT); } protected: typedef std::map RTMap; typedef RTMap::iterator RTMap_i; typedef RTMap::const_iterator RTMap_ci; RTMap renderTargets; void DoBind(void) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->objectID); std::vector colorDrawBuffers; colorDrawBuffers.reserve(this->renderTargets.size()); for (RTMap_i rt=this->renderTargets.begin(); rt!=this->renderTargets.end(); ++rt) { RenderTarget * prt = (*rt).second; if (prt->Semantic() == FrameBufferSemantic::COLOR) { colorDrawBuffers.push_back(prt->Attachment()); } prt->BindToFB(); } const GLsizei sz = (GLsizei)(colorDrawBuffers.size()); if (sz > 0) { glDrawBuffers(sz, &(colorDrawBuffers[0])); } } void DoUnbind(void) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } bool AddRT(RenderTarget * rt) { if (rt == 0) return false; RTMap_i it = this->renderTargets.find(rt->Attachment()); if (it == this->renderTargets.end()) { this->renderTargets.insert(std::make_pair(rt->Attachment(), rt)); return true; } return false; } bool RemoveRT(RenderTarget * rt) { if (rt == 0) return false; RTMap_i it = this->renderTargets.find(rt->Attachment()); if ((*it).second == rt) { this->renderTargets.erase(it); return true; } return false; } }; bool RenderTarget::Attach(FrameBuffer * fb) { this->Detach(); if (fb == 0) return true; if (fb->AddRT(this)) { this->frameBuffer = fb; return true; } return false; } bool RenderTarget::Detach(void) { if (this->frameBuffer == 0) return false; this->frameBuffer->RemoveRT(this); this->frameBuffer = 0; return true; } #endif // __FBO_H__ meshlab-1.3.2+dfsg1/vcglib/wrap/gl/gl_surface.h0000644000175000017500000003330711644553164020201 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.1 2007/07/26 16:22:47 m_di_benedetto First Commit. ****************************************************************************/ #ifndef VCGLIB_GL_SURFACE_H #define VCGLIB_GL_SURFACE_H #include #include namespace vcg { /**************************************************************************** The gl_surface class simplify the render-to-texture OpenGL functionality. It provides a framebuffer composed of single or multiple color buffers and a depth buffer; color-only and depth-only framebuffers can also be created. Sample usage: **************************************************************** // *** declaration gl_surface my_srf; *********************** // *** initialization: single color render target, with depth buffer { std::vector color_formats; color_formats.push_back(GL_RGBA8); my_srf.set(width, height, color_formats, GL_DEPTH_COMPONENT); } *********************** *********************** // *** initialization: two color render targets, without depth buffer // NOTE: the maximum number of color targets is implementation dependent. // NOTE: DX10 class hardware allows different formats for each color target. { std::vector color_formats; color_formats.push_back(GL_RGBA8); color_formats.push_back(GL_RGBA8); my_srf.set(width, height, color_formats, GL_NONE); } *********************** *********************** // *** usage: render-to-targets { my_srf.begin_write(); application_draw_code(); my_srf.end_write(); } *********************** *********************** // *** usage: using rendered textures { // 2 buffers // bind the second glActiveTexture(GL_TEXTURE1); my_srf.begin_read_color(1); // actually does a glBindTexture(); // bind the first glActiveTexture(GL_TEXTURE0); my_srf.begin_read_color(0); application_draw_code(); // unbind the second glActiveTexture(GL_TEXTURE1); my_srf.end_read_color(1); // unbind first glActiveTexture(GL_TEXTURE0); my_srf.end_read_color(0); } *********************** // *** usage: use depth map { my_srf.begin_read_depth(); // use depth map here application_draw_code(); my_srf.end_read_depth(); } *********************** // *** usage: cleanup { my_srf.clear(); // clear() is also safely called in the destructor. } *********************** Other commodity methods for getting/setting pixels are also provided. ****************************************************************************/ class gl_surface { public: typedef gl_surface this_type; gl_surface(void) : width(0), height(0), depth_tex(0), fb(0) { ; } ~gl_surface(void) { this->clear(); } bool set(int width, int height, const std::vector & color_formats, GLenum depth_format) { this->clear(); this->width = width; this->height = height; this->color_formats = color_formats; this->color_texs.resize(color_formats.size()); for (size_t i=0; icolor_texs.size(); ++i) { glGenTextures (1, &(this->color_texs[i])); glBindTexture (GL_TEXTURE_2D, this->color_texs[i]); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D (GL_TEXTURE_2D, 0, this->color_formats[i], this->width, this->height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, 0); } this->depth_format = depth_format; if (this->depth_format != GL_NONE) { glGenTextures (1, &(this->depth_tex)); glBindTexture (GL_TEXTURE_2D, this->depth_tex); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); glTexImage2D (GL_TEXTURE_2D, 0, this->depth_format, this->width, this->height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0); } glGenFramebuffersEXT(1, &(this->fb)); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->fb); std::vector sites(this->color_texs.size()); for (size_t i=0; icolor_texs.size(); ++i) { sites[i] = GL_COLOR_ATTACHMENT0_EXT + ((GLenum)i); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, sites[i], GL_TEXTURE_2D, this->color_texs[i], 0); } if (this->depth_format != GL_NONE) { glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, this->depth_tex, 0); } if (!sites.empty()) { glDrawBuffers((GLsizei)(sites.size()), &(sites[0])); } const GLenum s = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); const bool res = (s == GL_FRAMEBUFFER_COMPLETE_EXT); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); if (!res) { glDeleteFramebuffersEXT(1, &(this->fb)); this->fb = 0; for (size_t i=0; icolor_texs.size(); ++i) { glDeleteTextures(1, &(this->color_texs[i])); } this->color_texs.clear(); this->color_formats.clear(); if (this->depth_tex != 0) { glDeleteTextures(1, &(this->depth_tex)); this->depth_tex = 0; } this->width = 0; this->height = 0; return false; } return true; } bool set_simple(int width, int height) { std::vector c_formats; c_formats.push_back(GL_RGBA8); return this->set(width, height, c_formats, GL_DEPTH_COMPONENT); } bool set_color_only(int width, int height, GLenum color_format) { std::vector c_formats; c_formats.push_back(color_format); return this->set(width, height, c_formats, GL_NONE); } bool set_color_only(int width, int height, const std::vector & color_formats) { return this->set(width, height, color_formats, GL_NONE); } bool set_depth_only(int width, int height, GLenum depth_format) { std::vector c_formats; return this->set(width, height, c_formats, depth_format); } bool clear(void) { if (!this->is_valid()) return false; glDeleteFramebuffersEXT(1, &(this->fb)); this->fb = 0; for (size_t i=0; icolor_texs.size(); ++i) { glDeleteTextures(1, &(this->color_texs[i])); } this->color_texs.clear(); this->color_formats.clear(); if (this->depth_tex != 0) { glDeleteTextures(1, &(this->depth_tex)); this->depth_tex = 0; } this->width = 0; this->height = 0; return true; } bool is_valid(void) const { return (this->fb != 0); } int get_width(void) const { return this->width; } int get_height(void) const { return this->height; } int color_attachments_count(void) const { return ((int)(this->color_texs.size())); } GLenum get_color_attachment_format(int attachment) const { if (!this->is_valid()) return GL_NONE; if ((attachment < 0) || (attachment >= this->color_attachments_count())) return GL_NONE; return this->color_formats[attachment]; } bool has_depth_attachment(void) const { return (this->depth_tex != 0); } GLenum get_depth_attachment_format(void) const { if (!this->is_valid()) return GL_NONE; if (!this->has_depth_attachment()) return GL_NONE; return this->depth_format; } bool set_color_pixels(int attachment, GLenum format, GLenum type, const void * pixels) { if (!this->begin_read_color(attachment)) return false; glTexImage2D(GL_TEXTURE_2D, 0, this->color_formats[attachment], this->width, this->height, 0, format, type, pixels); this->end_read_color(attachment); return true; } bool get_color_pixels(int attachment, GLenum format, GLenum type, void * pixels) { if (!this->begin_read_color(attachment)) return false; glGetTexImage(GL_TEXTURE_2D, 0, format, type, pixels); this->end_read_color(attachment); return true; } bool set_depth_pixels(GLenum format, GLenum type, const void * pixels) { if (!this->is_valid()) return false; if (!this->has_depth_attachment()) return false; glTexImage2D(GL_TEXTURE_2D, 0, this->depth_format, this->width, this->height, 0, format, type, pixels); return true; } bool get_depth_pixels(GLenum format, GLenum type, void * pixels) { if (!this->begin_read_depth()) return false; glGetTexImage(GL_TEXTURE_2D, 0, format, type, pixels); this->end_read_depth(); return true; } bool begin_read_color(int attachment) { if (!this->is_valid()) return false; if ((attachment < 0) || (attachment >= this->color_attachments_count())) return false; glBindTexture(GL_TEXTURE_2D, this->color_texs[attachment]); return true; } bool end_read_color(int attachment) { if (!this->is_valid()) return false; if ((attachment < 0) || (attachment >= this->color_attachments_count())) return false; glBindTexture(GL_TEXTURE_2D, 0); return true; } bool begin_read_depth(void) { if (!this->is_valid()) return false; if (!this->has_depth_attachment()) return false; glBindTexture(GL_TEXTURE_2D, this->depth_tex); return true; } bool end_read_depth(void) { if (!this->is_valid()) return false; if (!this->has_depth_attachment()) return false; glBindTexture(GL_TEXTURE_2D, 0); return true; } bool begin_write(void) { if (!this->is_valid()) return false; glPushAttrib(GL_VIEWPORT_BIT); glViewport(0, 0, this->width, this->height); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->fb); return true; } bool end_write(void) { if (!this->is_valid()) return false; glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glPopAttrib(); return true; } bool draw_color_attachment(int x, int y, int width, int height, int attachment) { if (!this->is_valid()) return false; if ((attachment < 0) || (attachment >= this->color_attachments_count())) return false; glPushAttrib(GL_ALL_ATTRIB_BITS); glViewport(x, y, width, height); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); this->begin_read_color(attachment); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f); glEnd(); this->end_read_color(attachment); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); return true; } bool draw_depth_attachment(int x, int y, int width, int height) { if (!this->is_valid()) return false; if (!this->has_depth_attachment()) return false; glPushAttrib(GL_ALL_ATTRIB_BITS); glViewport(x, y, width, height); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); this->begin_read_depth(); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f); glEnd(); this->end_read_depth(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); return true; } protected: int width; int height; std::vector color_formats; std::vector color_texs; GLenum depth_format; GLuint depth_tex; GLuint fb; }; } // end namespace vcg #endif // VCGLIB_GL_SURFACE_H meshlab-1.3.2+dfsg1/vcglib/wrap/gl/glu_tesselator.h0000644000175000017500000001626711761424115021122 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef __VCGLIB_GLU_TESSELATOR_H #define __VCGLIB_GLU_TESSELATOR_H #include #include #ifndef GL_VERSION_1_1 #error "Please include OpenGL before including this file" #endif // The inclusion of glu should be always safe (if someone has already included gl stuff). #ifndef GLU_VERSIONS #ifdef __APPLE__ #include #else #ifdef _WIN32 #include #endif #include #endif #endif #ifndef CALLBACK #ifdef _WIN32 #define CALLBACK __stdcall #else #define CALLBACK #endif #endif namespace vcg { class glu_tesselator { public: typedef glu_tesselator this_type; /* Works with Point2 and Point3; sample usage: // tesselation input: each outline represents a polygon contour std::vector< std::vector > outlines = ...; // tesselation output (triangles indices) std::vector indices; // compute triangles indices glu_tesselator::tesselate(outlines, indices); // unroll input contours points std::vector points; for (size_t i=0; i static inline void unroll(const std::vector< std::vector > & outlines, std::vector & points) { for (size_t i=0; i static inline void tesselate(const std::vector< std::vector > & outlines, std::vector & indices) { tess_prim_data_vec t_data; this_type::do_tesselation(outlines, t_data); //int k = 0; for (size_t i=0; i indices; tess_prim_data(void) { } tess_prim_data(GLenum t) : type(t) { } }; typedef std::vector tess_prim_data_vec; static void CALLBACK begin_cb(GLenum type, void * polygon_data) { tess_prim_data_vec * t_data = (tess_prim_data_vec *)polygon_data; t_data->push_back(tess_prim_data(type)); } static void CALLBACK end_cb(void * polygon_data) { (void)polygon_data; } static void CALLBACK vertex_cb(void * vertex_data, void * polygon_data) { tess_prim_data_vec * t_data = (tess_prim_data_vec *)polygon_data; t_data->back().indices.push_back((int)((size_t)vertex_data)); } template static void do_tesselation(const std::vector< std::vector > & outlines, tess_prim_data_vec & t_data) { GLUtesselator * tess = gluNewTess(); //#ifdef __APPLE__ // gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (GLvoid (CALLBACK *)(...))(this_type::begin_cb)); // gluTessCallback(tess, GLU_TESS_END_DATA, (GLvoid (CALLBACK *)(...))(this_type::end_cb)); // gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (GLvoid (CALLBACK *)(...))(this_type::vertex_cb)); //#else gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (GLvoid (CALLBACK *)())(this_type::begin_cb)); gluTessCallback(tess, GLU_TESS_END_DATA, (GLvoid (CALLBACK *)())(this_type::end_cb)); gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (GLvoid (CALLBACK *)())(this_type::vertex_cb)); //#endif void * polygon_data = (void *)(&t_data); GLdouble vertex[3]; int k = 0; gluTessBeginPolygon(tess, polygon_data); for (size_t i=0; i static inline void get_position(const vcg::Point2 & p, GLdouble * d) { d[0] = (GLdouble)(p[0]); d[1] = (GLdouble)(p[1]); d[2] = (GLdouble)(0); } template static inline void get_position(const vcg::Point3 & p, GLdouble * d) { d[0] = (GLdouble)(p[0]); d[1] = (GLdouble)(p[1]); d[2] = (GLdouble)(p[2]); } }; } // end namespace vcg #endif // __VCGLIB_GLU_TESSELATOR_H meshlab-1.3.2+dfsg1/vcglib/wrap/gl/trimesh.h0000644000175000017500000007203411732414760017536 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef __VCG_GLTRIMESH #define __VCG_GLTRIMESH #include #include //#include #include #include #include namespace vcg { // classe base di glwrap usata solo per poter usare i vari drawmode, normalmode senza dover // specificare tutto il tipo (a volte lunghissimo) // della particolare classe glwrap usata. class GLW { public: enum DrawMode {DMNone, DMBox, DMPoints, DMWire, DMHidden, DMFlat, DMSmooth, DMFlatWire, DMRadar, DMLast} ; enum NormalMode {NMNone, NMPerVert, NMPerFace, NMPerWedge, NMLast}; enum ColorMode {CMNone, CMPerMesh, CMPerFace, CMPerVert, CMLast}; enum TextureMode{TMNone, TMPerVert, TMPerWedge, TMPerWedgeMulti}; enum Hint { HNUseTriStrip = 0x0001, // ha bisogno che ci sia la fftopology gia calcolata! // HNUseEdgeStrip = 0x0002, // HNUseDisplayList = 0x0004, HNCacheDisplayList = 0x0008, // Each mode has its dl; HNLazyDisplayList = 0x0010, // Display list are generated only when requested HNIsTwoManifold = 0x0020, // There is no need to make DetachComplex before . HNUsePerWedgeNormal = 0x0040, // HNHasFFTopology = 0x0080, // E' l'utente che si preoccupa di tenere aggiornata la topologia ff HNHasVFTopology = 0x0100, // E' l'utente che si preoccupa di tenere aggiornata la topologia vf HNHasVertNormal = 0x0200, // E' l'utente che si preoccupa di tenere aggiornata le normali per faccia HNHasFaceNormal = 0x0400, // E' l'utente che si preoccupa di tenere aggiornata le normali per vertice HNUseVArray = 0x0800, HNUseLazyEdgeStrip = 0x1000, // Edge Strip are generated only when requested HNUseVBO = 0x2000, // Use Vertex Buffer Object HNIsPolygonal = 0x4000 // In wireframe modes, hide faux edges }; enum Change { CHVertex = 0x01, CHNormal = 0x02, CHColor = 0x04, CHFace = 0x08, CHFaceNormal = 0x10, CHRender = 0x20, CHAll = 0xff }; enum HintParami { HNPDisplayListSize =0, HNPPointDistanceAttenuation =1, HNPPointSmooth = 2 }; enum HintParamf { HNPCreaseAngle =0, // crease angle in radians HNPZTwist = 1, // Z offset used in Flatwire and hiddenline modality HNPPointSize = 2 // the point size used in point rendering }; template class VertToSplit { public: typename MESH_TYPE::face_base_pointer f; char z; char edge; bool newp; typename MESH_TYPE::vertex_pointer v; }; // GL Array Elemet class GLAElem { public : int glmode; int len; int start; }; }; template > class GlTrimesh : public GLW { public: typedef MESH_TYPE mesh_type; FACE_POINTER_CONTAINER face_pointers; std::vector TMId; unsigned int array_buffers[3]; int curr_hints; // the current hints // The parameters of hints int HNParami[8]; float HNParamf[8]; MESH_TYPE *m; GlTrimesh() { m=0; dl=0xffffffff; curr_hints=HNUseLazyEdgeStrip; cdm=DMNone; ccm=CMNone; cnm=NMNone; SetHintParamf(HNPCreaseAngle,float(M_PI/5)); SetHintParamf(HNPZTwist,0.00005f); SetHintParamf(HNPPointSize,1.0f); SetHintParami(HNPPointDistanceAttenuation, 1); SetHintParami(HNPPointSmooth, 0); } ~GlTrimesh() { //Delete the VBOs if(curr_hints&HNUseVBO) { for(int i=0;i<3;++i) if(glIsBuffer(array_buffers[i])) glDeleteBuffersARB(1, (GLuint *)(array_buffers+i)); } } void SetHintParami(const HintParami hip, const int value) { HNParami[hip]=value; } int GetHintParami(const HintParami hip) const { return HNParami[hip]; } void SetHintParamf(const HintParamf hip, const float value) { HNParamf[hip]=value; } float GetHintParamf(const HintParamf hip) const { return HNParamf[hip]; } void SetHint(Hint hn) { curr_hints |= hn; } void ClearHint(Hint hn) { curr_hints&=(~hn); } unsigned int dl; std::vector indices; DrawMode cdm; // Current DrawMode NormalMode cnm; // Current NormalMode ColorMode ccm; // Current ColorMode void Update(/*Change c=CHAll*/) { if(m==0) return; if(curr_hints&HNUseVArray || curr_hints&HNUseVBO) { typename MESH_TYPE::FaceIterator fi; indices.clear(); for(fi = m->face.begin(); fi != m->face.end(); ++fi) { indices.push_back((unsigned int)((*fi).V(0) - &(*m->vert.begin()))); indices.push_back((unsigned int)((*fi).V(1) - &(*m->vert.begin()))); indices.push_back((unsigned int)((*fi).V(2) - &(*m->vert.begin()))); } if(curr_hints&HNUseVBO) { if(!glIsBuffer(array_buffers[1])) glGenBuffers(2,(GLuint*)array_buffers); glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]); glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType), (char *)&(m->vert[0].P()), GL_STATIC_DRAW_ARB); glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]); glBufferData(GL_ARRAY_BUFFER_ARB, m->vn * sizeof(typename MESH_TYPE::VertexType), (char *)&(m->vert[0].N()), GL_STATIC_DRAW_ARB); } glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0); glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0); } //int C=c; //if((C&CHVertex) || (C&CHFace)) { // ComputeBBox(*m); // if(!(curr_hints&HNHasFaceNormal)) m->ComputeFaceNormal(); // if(!(curr_hints&HNHasVertNormal)) m->ComputeVertexNormal(); // C= (C | CHFaceNormal); //} //if((C&CHFace) && (curr_hints&HNUseEdgeStrip)) ComputeEdges(); //if((C&CHFace) && (curr_hints&HNUseLazyEdgeStrip)) ClearEdges(); //if(MESH_TYPE::HasFFTopology()) // if((C&CHFace) && (curr_hints&HNUseTriStrip)) { // if(!(curr_hints&HNHasFFTopology)) m->FFTopology(); // ComputeTriStrip(); // } //if((C&CHFaceNormal) && (curr_hints&HNUsePerWedgeNormal)) { // if(!(curr_hints&HNHasVFTopology)) m->VFTopology(); // CreaseWN(*m,MESH_TYPE::scalar_type(GetHintParamf(HNPCreaseAngle))); //} //if(C!=0) { // force the recomputation of display list // cdm=DMNone; // ccm=CMNone; // cnm=NMNone; //} //if((curr_hints&HNUseVArray) && (curr_hints&HNUseTriStrip)) // { // ConvertTriStrip(*m,TStrip,TStripF,TStripVED,TStripVEI); // } } void Draw(DrawMode dm ,ColorMode cm, TextureMode tm) { switch(dm) { case DMNone : Draw(cm,tm); break; case DMBox : Draw(cm,tm); break; case DMPoints : Draw(cm,tm); break; case DMWire : Draw(cm,tm); break; case DMHidden : Draw(cm,tm); break; case DMFlat : Draw(cm,tm); break; case DMSmooth : Draw(cm,tm); break; case DMFlatWire: Draw(cm,tm); break; default : break; } } template< DrawMode dm > void Draw(ColorMode cm, TextureMode tm) { switch(cm) { case CMNone : Draw(tm); break; case CMPerMesh : Draw(tm); break; case CMPerFace : Draw(tm); break; case CMPerVert : Draw(tm); break; default : break; } } template< DrawMode dm, ColorMode cm > void Draw(TextureMode tm) { switch(tm) { case TMNone : Draw(); break; case TMPerVert : Draw(); break; case TMPerWedge : Draw(); break; case TMPerWedgeMulti : Draw(); break; default : break; } } template< DrawMode dm, ColorMode cm, TextureMode tm> void Draw() { if(!m) return; if((curr_hints & HNUseDisplayList)){ if (cdm==dm && ccm==cm){ glCallList(dl); return; } else { if(dl==0xffffffff) dl=glGenLists(1); glNewList(dl,GL_COMPILE); } } glPushMatrix(); switch(dm) { case DMNone : break; case DMBox : DrawBBox(cm);break; case DMPoints : DrawPoints();break; case DMHidden : DrawHidden();break; case DMFlat : DrawFill();break; case DMFlatWire : DrawFlatWire();break; case DMRadar : DrawRadar();break; case DMWire : DrawWire();break; case DMSmooth : DrawFill();break; default : break; } glPopMatrix(); if((curr_hints & HNUseDisplayList)){ cdm=dm; ccm=cm; glEndList(); glCallList(dl); } } /*********************************************************************************************/ /*********************************************************************************************/ template void DrawFill() { if(m->fn==0) return; typename FACE_POINTER_CONTAINER::iterator fp; typename MESH_TYPE::FaceIterator fi; typename std::vector::iterator fip; short curtexname=-1; if(cm == CMPerMesh) glColor(m->C()); if(tm == TMPerWedge || tm == TMPerWedgeMulti ) glDisable(GL_TEXTURE_2D); if(curr_hints&HNUseVBO) { if( (cm==CMNone) || (cm==CMPerMesh) ) { if (nm==NMPerVert) glEnableClientState (GL_NORMAL_ARRAY); glEnableClientState (GL_VERTEX_ARRAY); if (nm==NMPerVert) { glBindBuffer(GL_ARRAY_BUFFER,array_buffers[1]); glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0); } glBindBuffer(GL_ARRAY_BUFFER,array_buffers[0]); glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),0); glDrawElements(GL_TRIANGLES ,m->fn*3,GL_UNSIGNED_INT, &(*indices.begin()) ); glDisableClientState (GL_VERTEX_ARRAY); if (nm==NMPerVert) glDisableClientState (GL_NORMAL_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); return; } } if(curr_hints&HNUseVArray) { if( (cm==CMNone) || (cm==CMPerMesh) ) { if (nm==NMPerVert) glEnableClientState (GL_NORMAL_ARRAY); glEnableClientState (GL_VERTEX_ARRAY); if (nm==NMPerVert) glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->N()[0])); glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->P()[0])); glDrawElements(GL_TRIANGLES ,m->fn*3,GL_UNSIGNED_INT, &(*indices.begin()) ); glDisableClientState (GL_VERTEX_ARRAY); if (nm==NMPerVert) glDisableClientState (GL_NORMAL_ARRAY); return; } } else if(curr_hints&HNUseTriStrip) { //if( (nm==NMPerVert) && ((cm==CMNone) || (cm==CMPerMesh))) // if(curr_hints&HNUseVArray){ // glEnableClientState (GL_NORMAL_ARRAY ); // glNormalPointer(GL_FLOAT,sizeof(MESH_TYPE::VertexType),&(m->vert[0].cN())); // glEnableClientState (GL_VERTEX_ARRAY); // glVertexPointer(3,GL_FLOAT,sizeof(MESH_TYPE::VertexType),&(m->vert[0].cP())); // std::vector::iterator vi; // for(vi=TStripVED.begin();vi!=TStripVED.end();++vi) // glDrawElements(vi->glmode ,vi->len,GL_UNSIGNED_SHORT,&TStripVEI[vi->start] ); // // glDisableClientState (GL_NORMAL_ARRAY ); // glDisableClientState (GL_VERTEX_ARRAY); // return; // } //std::vector< MESH_TYPE::VertexType *>::iterator vi; //glBegin(GL_TRIANGLE_STRIP); //if(nm == NMPerFace) fip=TStripF.begin(); //for(vi=TStrip.begin();vi!=TStrip.end(); ++vi){ // if((*vi)){ // if(nm==NMPerVert) glNormal((*vi)->cN()); // if(nm==NMPerFace) glNormal((*fip)->cN()); // glVertex((*vi)->P()); // } // else // { // glEnd(); // glBegin(GL_TRIANGLE_STRIP); // } // if(nm == NMPerFace) ++fip; // } //glEnd(); } else { if(partial) fp = face_pointers.begin(); else fi = m->face.begin(); if(tm==TMPerWedgeMulti) { curtexname=(*fi).WT(0).n(); if (curtexname >= 0) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,TMId[curtexname]); } else { glDisable(GL_TEXTURE_2D); } } if(tm==TMPerWedge) glEnable(GL_TEXTURE_2D); if(tm==TMPerVert && !TMId.empty()) // in the case of per vertex tex coord we assume that we have a SINGLE texture. { curtexname = 0; glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,TMId[curtexname]); } glBegin(GL_TRIANGLES); while( (partial)?(fp!=face_pointers.end()):(fi!=m->face.end())) { typename MESH_TYPE::FaceType & f = (partial)?(*(*fp)): *fi; if(!f.IsD()) { if(tm==TMPerWedgeMulti) if(f.WT(0).n() != curtexname) { curtexname=(*fi).WT(0).n(); glEnd(); if (curtexname >= 0) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,TMId[curtexname]); } else { glDisable(GL_TEXTURE_2D); } glBegin(GL_TRIANGLES); } if(nm == NMPerFace) glNormal(f.cN()); if(nm == NMPerVert) glNormal(f.V(0)->cN()); if(nm == NMPerWedge)glNormal(f.WN(0)); if(cm == CMPerFace) glColor(f.C()); if(cm == CMPerVert) glColor(f.V(0)->C()); if(tm==TMPerVert) glTexCoord(f.V(0)->T().P()); if( (tm==TMPerWedge)||(tm==TMPerWedgeMulti) )glTexCoord(f.WT(0).t(0)); glVertex(f.V(0)->P()); if(nm == NMPerVert) glNormal(f.V(1)->cN()); if(nm == NMPerWedge)glNormal(f.WN(1)); if(cm == CMPerVert) glColor(f.V(1)->C()); if(tm==TMPerVert) glTexCoord(f.V(1)->T().P()); if( (tm==TMPerWedge)|| (tm==TMPerWedgeMulti)) glTexCoord(f.WT(1).t(0)); glVertex(f.V(1)->P()); if(nm == NMPerVert) glNormal(f.V(2)->cN()); if(nm == NMPerWedge)glNormal(f.WN(2)); if(cm == CMPerVert) glColor(f.V(2)->C()); if(tm==TMPerVert) glTexCoord(f.V(2)->T().P()); if( (tm==TMPerWedge)|| (tm==TMPerWedgeMulti)) glTexCoord(f.WT(2).t(0)); glVertex(f.V(2)->P()); } if(partial) ++fp; else ++fi; } glEnd(); } } // A draw wireframe that hides faux edges template void DrawWirePolygonal() { typename MESH_TYPE::FaceIterator fi; typename FACE_POINTER_CONTAINER::iterator fp; typename std::vector::iterator fip; if(cm == CMPerMesh) glColor(m->C()); { if(partial) fp = face_pointers.begin(); else fi = m->face.begin(); glBegin(GL_LINES); while( (partial)?(fp!=face_pointers.end()):(fi!=m->face.end())) { typename MESH_TYPE::FaceType & f = (partial)?(*(*fp)): *fi; if(!f.IsD()) { if(nm == NMPerFace) glNormal(f.cN()); if(cm == CMPerFace) glColor(f.C()); if (!f.IsF(0)) { if(nm == NMPerVert) glNormal(f.V(0)->cN()); if(nm == NMPerWedge)glNormal(f.WN(0)); if(cm == CMPerVert) glColor(f.V(0)->C()); glVertex(f.V(0)->P()); if(nm == NMPerVert) glNormal(f.V(1)->cN()); if(nm == NMPerWedge)glNormal(f.WN(1)); if(cm == CMPerVert) glColor(f.V(1)->C()); glVertex(f.V(1)->P()); } if (!f.IsF(1)) { if(nm == NMPerVert) glNormal(f.V(1)->cN()); if(nm == NMPerWedge)glNormal(f.WN(1)); if(cm == CMPerVert) glColor(f.V(1)->C()); glVertex(f.V(1)->P()); if(nm == NMPerVert) glNormal(f.V(2)->cN()); if(nm == NMPerWedge)glNormal(f.WN(2)); if(cm == CMPerVert) glColor(f.V(2)->C()); glVertex(f.V(2)->P()); } if (!f.IsF(2)) { if(nm == NMPerVert) glNormal(f.V(2)->cN()); if(nm == NMPerWedge)glNormal(f.WN(2)); if(cm == CMPerVert) glColor(f.V(2)->C()); glVertex(f.V(2)->P()); if(nm == NMPerVert) glNormal(f.V(0)->cN()); if(nm == NMPerWedge)glNormal(f.WN(0)); if(cm == CMPerVert) glColor(f.V(0)->C()); glVertex(f.V(0)->P()); } } if(partial) ++fp; else ++fi; } glEnd(); } } /// Basic Point drawing fucntion // works also for mesh with deleted vertices template void DrawPointsBase() { typename MESH_TYPE::VertexIterator vi; glBegin(GL_POINTS); if(cm==CMPerMesh) glColor(m->C()); for(vi=m->vert.begin();vi!=m->vert.end();++vi)if(!(*vi).IsD()) { if(nm==NMPerVert) glNormal((*vi).cN()); if(cm==CMPerVert) glColor((*vi).C()); glVertex((*vi).P()); } glEnd(); } /// Utility function that computes in eyespace the current distance between the camera and the center of the bbox of the mesh double CameraDistance(){ Point3 res; Matrix44 mm; glGetv(GL_MODELVIEW_MATRIX,mm); Point3 c=m->bbox.Center(); res=mm*c; return Norm(res); } template void DrawPoints() { glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT); if(GetHintParami(HNPPointSmooth)>0) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH); glPointSize(GetHintParamf(HNPPointSize)); if (glPointParameterfv) { if(GetHintParami(HNPPointDistanceAttenuation)>0) { float camDist = (float)CameraDistance(); float quadratic[] = { 0.0f, 0.0f, 1.0f/(camDist*camDist) , 0.0f }; glPointParameterfv( GL_POINT_DISTANCE_ATTENUATION, quadratic ); glPointParameterf( GL_POINT_SIZE_MAX, 16.0f ); glPointParameterf( GL_POINT_SIZE_MIN, 1.0f ); } else { float quadratic[] = { 1.0f, 0.0f, 0.0f}; glPointParameterfv( GL_POINT_DISTANCE_ATTENUATION, quadratic ); glPointSize(GetHintParamf(HNPPointSize)); } } if(m->vn!=(int)m->vert.size()) { DrawPointsBase(); } else { if(cm==CMPerMesh) glColor(m->C()); // Perfect case, no deleted stuff, // draw the vertices using vertex arrays if (nm==NMPerVert) { glEnableClientState (GL_NORMAL_ARRAY); if (m->vert.size() != 0) glNormalPointer(GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->N()[0])); } if (cm==CMPerVert) { glEnableClientState (GL_COLOR_ARRAY); if (m->vert.size() != 0) glColorPointer(4,GL_UNSIGNED_BYTE,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->C()[0])); } glEnableClientState (GL_VERTEX_ARRAY); if (m->vert.size() != 0) glVertexPointer(3,GL_FLOAT,sizeof(typename MESH_TYPE::VertexType),&(m->vert.begin()->P()[0])); glDrawArrays(GL_POINTS,0,m->vn); glDisableClientState (GL_VERTEX_ARRAY); if (nm==NMPerVert) glDisableClientState (GL_NORMAL_ARRAY); if (cm==CMPerVert) glDisableClientState (GL_COLOR_ARRAY); } glPopAttrib(); return; } void DrawHidden() { //const float ZTWIST=HNParamf[HNPZTwist]; glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT ); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0, 1); //glDepthRange(ZTWIST,1.0f); glDisable(GL_LIGHTING); glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); DrawFill(); glDisable(GL_POLYGON_OFFSET_FILL); glEnable(GL_LIGHTING); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); //glDepthRange(0.0f,1.0f-ZTWIST); DrawWire(); glPopAttrib(); // glDepthRange(0,1.0f); } template void DrawFlatWire() { //const float ZTWIST=HNParamf[HNPZTwist]; //glDepthRange(ZTWIST,1.0f); glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT ); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0, 1); DrawFill(); glDisable(GL_POLYGON_OFFSET_FILL); //glDepthRange(0.0f,1.0f-ZTWIST); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); //glColorMaterial(GL_FRONT,GL_DIFFUSE); glColor3f(.3f,.3f,.3f); DrawWire(); glPopAttrib(); //glDepthRange(0,1.0f); } template void DrawRadar() { const float ZTWIST=HNParamf[HNPZTwist]; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(0); glDepthRange(ZTWIST,1.0f); if (cm == CMNone) glColor4f(0.2f, 1.0f, 0.4f, 0.2f); // DrawFill(); Draw(); glDepthMask(1); glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); // DrawFill(); Draw(); glDepthRange(0.0f,1.0f-ZTWIST); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glColor4f(0.1f, 1.0f, 0.2f, 0.6f); Draw(); glDisable(GL_BLEND); glDepthRange(0,1.0f); } #ifdef GL_TEXTURE0_ARB // Multitexturing nel caso voglia usare due texture unit. void DrawTexture_NPV_TPW2() { unsigned int texname=(*(m->face.begin())).WT(0).n(0); glBindTexture(GL_TEXTURE_2D,TMId[texname]); typename MESH_TYPE::FaceIterator fi; glBegin(GL_TRIANGLES); for(fi=m->face.begin();fi!=m->face.end();++fi)if(!(*fi).IsD()){ if(texname!=(*fi).WT(0).n(0)) { texname=(*fi).WT(0).n(0); glEnd(); glBindTexture(GL_TEXTURE_2D,TMId[texname]); glBegin(GL_TRIANGLES); } glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(0).t(0)); glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(0).t(0)); glNormal((*fi).V(0)->N()); glVertex((*fi).V(0)->P()); glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(1).t(0)); glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(1).t(0)); glNormal((*fi).V(1)->N()); glVertex((*fi).V(1)->P()); glMultiTexCoordARB(GL_TEXTURE0_ARB, (*fi).WT(2).t(0)); glMultiTexCoordARB(GL_TEXTURE1_ARB, (*fi).WT(2).t(0)); glNormal((*fi).V(2)->N()); glVertex((*fi).V(2)->P()); } glEnd(); } #endif /*int MemUsed() { int tot=sizeof(GlTrimesh); tot+=sizeof(mesh_type::edge_type)*edge.size(); tot+=sizeof(MESH_TYPE::VertexType *) * EStrip.size(); tot+=sizeof(MESH_TYPE::VertexType *) * TStrip.size(); tot+=sizeof(MESH_TYPE::FaceType *) * TStripF.size(); return tot; }*/ private: template void DrawWire() { //if(!(curr_hints & (HNUseEdgeStrip | HNUseLazyEdgeStrip) ) ) if ( (curr_hints & HNIsPolygonal) ) { DrawWirePolygonal(); } else { glPushAttrib(GL_POLYGON_BIT); glPolygonMode(GL_FRONT_AND_BACK ,GL_LINE); DrawFill(); glPopAttrib(); } if(m->fn==0 && m->en>0) { glPushAttrib(GL_ENABLE_BIT); glDisable(GL_LIGHTING); glBegin(GL_LINES); for(typename mesh_type::EdgeIterator ei=m->edge.begin();ei!=m->edge.end(); ++ei) { glVertex((*ei).V(0)->P()); glVertex((*ei).V(1)->P()); } glEnd(); glPopAttrib(); } // { // if(!HasEdges()) ComputeEdges(); //if(cm==CMPerMesh) glColor(m->C()); //std::vector< MESH_TYPE::VertexType *>::iterator vi; //glBegin(GL_LINE_STRIP); //for(vi=EStrip.begin();vi!=EStrip.end(); ++vi){ // if((*vi)){ // glNormal((*vi)->N()); // glVertex((*vi)->P()); // } // else // { // glEnd(); // glBegin(GL_LINE_STRIP); // } //} //glEnd(); // } } void DrawBBox(ColorMode cm) { if(cm==CMPerMesh) glColor(m->C()); glBoxWire(m->bbox); } };// end class /* Crease Angle Assume che: la mesh abbia la topologia ff la mesh non abbia complex (o se li aveva fossero stati detached) Abbia le normali per faccia normalizzate!! Prende una mesh e duplica tutti gli edge le cui normali nelle facce incidenti formano un angolo maggiore di (espresso in rad). foreach face foreach unvisited vert vi scan the star of triangles around vi duplicating vi each time we encounter a crease angle. the new (and old) vertexes are put in a std::vector that is swapped with the original one at the end. */ // uncomment one of the following line to enable the Verbose Trace for Crease #define VCTRACE (void)0 //#define VCTRACE TRACE template void Crease(MESH_TYPE &m, typename MESH_TYPE::scalar_type angleRad) { assert(HasFFTopology(m)); typename MESH_TYPE::scalar_type cosangle=Cos(angleRad); std::vector > SPL; std::vector newvert; newvert.reserve(m.fn*3); // indica se un il vertice z della faccia e' stato processato enum {VISITED_0= MESH_TYPE::FaceType::USER0, VISITED_1= MESH_TYPE::FaceType::USER0<<1, VISITED_2= MESH_TYPE::FaceType::USER0<<2} ; int vis[3]={VISITED_0,VISITED_1,VISITED_2}; //int _t2=clock(); typename MESH_TYPE::FaceIterator fi; for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) (*fi).Supervisor_Flags()&= (~(VISITED_0 | VISITED_1 | VISITED_2)); for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) for(int j=0;j<3;++j) if(!((*fi).Supervisor_Flags() & (vis[j]))) { //VCTRACE("Face %i Spinning around vertex %i\n",fi-m.face.begin(), (*fi).V(j)-m.vert.begin()); //(*fi).Supervisor_Flags() |= vis[j]; typename MESH_TYPE::hedgepos_type he(&*fi,j,(*fi).V(j)); typename MESH_TYPE::hedgepos_type she=he; typename MESH_TYPE::face_base_pointer nextf; GLW::VertToSplit spl; spl.newp=false; spl.edge=-1; //Primo giro per trovare un bordo da cui partire do { he.FlipF(); he.FlipE(); if(he.IsBorder()) break; } while(he!=she); if(he==she) // non c'e'bordi allora si cerca un crease { do { he.FlipF(); he.FlipE(); nextf=he.f->F(he.z); typename MESH_TYPE::scalar_type ps=nextf->N()*he.f->N(); if(psV(he.z)) vz=he.z; if(he.v == he.f->V((he.z+1)%3)) vz=(he.z+1)%3; assert((he.f->Supervisor_Flags() & vis[vz] )==0); } while(he!=she); } he.FlipE(); she=he; newvert.push_back(*(*fi).V(j)); typename MESH_TYPE::vertex_pointer curvert=&newvert.back(); // VCTRACE("Starting from face %i edge %i vert %i \n",he.f-m.face.begin(), he.z, he.v-m.vert.begin()); // Secondo giro in cui si riempie il vettore SPL con tutte le info per fare i nuovi vertici do{ //TRACE(" -- spinning face %i edge %i vert %i\n",he.f-m.face.begin(), he.z, he.v-m.vert.begin()); spl.v=curvert; spl.f=he.f; spl.z=-1; if(he.v == he.f->V(he.z)) spl.z=he.z; if(he.v == he.f->V((he.z+1)%3)) spl.z=(he.z+1)%3; assert(spl.z>=0); //VCTRACE(" -- spinning face vert %i Adding spl face %i vert %i\n", // he.v-m.vert.begin(), spl.f-m.face.begin(), spl.z ); assert((spl.f->Supervisor_Flags() & vis[spl.z] )==0); spl.f->Supervisor_Flags() |= vis[spl.z]; SPL.push_back(spl); spl.newp=false; spl.edge=-1; if(he.IsBorder()) break; nextf=he.f->F(he.z); if(nextf==she.f) break; typename MESH_TYPE::scalar_type ps=nextf->N()*he.f->N(); if(ps >::iterator vsi; for(vsi=SPL.begin();vsi!=SPL.end();++vsi) { (*vsi).f->V((*vsi).z)=(*vsi).v; if((*vsi).newp){ assert((*vsi).edge>=0 && (*vsi).edge<3); if(!(*vsi).f->IsBorder( (*vsi).edge) ) (*vsi).f->Detach((*vsi).edge); } } m.vert.math::Swap(newvert); m.vn=m.vert.size(); } /* Secondo tipo di crease angle. ha bisogno del per wedge normal e delle adiacence per vertice faccia gia fatte; Assume che le normali per faccia siano gia'state fatte (se ci sono) */ /*template void CreaseWN(MESH_TYPE &m, typename MESH_TYPE::scalar_type angle) { if(!(MESH_TYPE::FaceType::OBJ_TYPE & MESH_TYPE::FaceType::OBJ_TYPE_WN) ) { assert(0); // You needs a mesh with faces having per wedge normals return; } typename MESH_TYPE::scalar_type cosangle=Cos(angle); typename MESH_TYPE::FaceIterator fi; // Clear the per wedge normals for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) { (*fi).WN(0)=MESH_TYPE::vectorial_type(0,0,0); (*fi).WN(1)=MESH_TYPE::vectorial_type(0,0,0); (*fi).WN(2)=MESH_TYPE::vectorial_type(0,0,0); } typename MESH_TYPE::FaceType::vectorial_type nn; for(fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD()) { nn=(*fi).cN(); for(int i=0;i<3;++i) { VEdgePosB x; for(x.f = (*fi).V(i)->Fp(), x.z = (*fi).V(i)->Zp(); x.f!=0; x.NextF() ) { assert(x.f->V(x.z)==(*fi).V(i)); if(x.f->cN()*nn > cosangle) x.f->WN(x.z)+=nn; } } } }*/ } // end namespace #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/tetramesh.h0000644000175000017500000002463711517500604020057 0ustar gladkgladk/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef __GLWRAPTETRA__ #define __GLWRAPTETRA__ #include #include #include #include #include #include #include namespace vcg { namespace tetra { class GLW { public: enum DrawMode {DMNone, DMSmallTetra,DMFlat,DMWire, DMHidden,DMTransparent,DMFlatWire} ; enum NormalMode{NMFlat,NMSmooth, NMUser, NMPerMesh}; enum ColorMode {CMNone, CMPerMesh,CMUser,CMPerTetraF,CMPerVertexF,CMPerVertex}; enum Hint {HShrinkFactor}; }; template class GlTetramesh:public GLW{ public: typedef typename CONT_TETRA::value_type TetraType; typedef typename TetraType::VertexType VertexType; typedef typename VertexType::ScalarType ScalarType; typedef typename VertexType::CoordType Point3x; //subclass for clipping planes class ClipPlane { private: Point3x D; Point3x D0; GLdouble eqn[4]; vcg::Matrix44 TR; Point3x pp0; Point3x pp1; Point3x pp2; Point3x pp3; public: bool active; Point3x P; ClipPlane (){active=false;} ~ClipPlane (){} ClipPlane(Point3x p0, Point3x p1,Point3x p2) { Point3x N=((p1-p0)^(p2-p0)).Normalize(); N.Normalize(); D=N; D0=D; P=(p0+p1+p2)/3.f; Point3x v0=N; Point3x v1=(P-p0); v1.Normalize(); Point3x v2=(v0^v1); v2.Normalize(); v0=v0*2; v1=v1*2; v2=v2*2; pp0=-v1-v2; pp1=-v1+v2; pp2=v1+v2; pp3=v1-v2; } //set normal of the clipping plane void SetD(Point3x d) { D=d; } //set the point of the clipping plane void SetP(Point3x p) { P=p; } void GlClip() { if (active){ GLdouble d=-(D.V(0)*P.V(0)+D.V(1)*P.V(1)+D.V(2)*P.V(2)); eqn[0]=-D.V(0); eqn[1]=-D.V(1); eqn[2]=-D.V(2); eqn[3]=-d; glClipPlane(GL_CLIP_PLANE0, eqn); glEnable(GL_CLIP_PLANE0); } } void GlDraw() { glPushMatrix(); glPushAttrib(0xffffffff); glDisable(GL_CLIP_PLANE0); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glTranslate(P); glMultMatrix(TR); glLineWidth(0.5); glColor3d(0.7,0,0.7); glBegin(GL_LINE_LOOP); glVertex(pp0); glVertex(pp1); glVertex(pp2); glVertex(pp3); glEnd(); glPopAttrib(); glPopMatrix(); } void Transform(vcg::Matrix44 Tr) { //thath's for casting in case of trackball using //float to double and vice-versa Point3f p=Point3f((float)D0.V(0),(float)D0.V(1),(float)D0.V(2)); TR=Tr; p=TR*p; D=Point3x((ScalarType) p.V(0),(ScalarType) p.V(1),(ScalarType) p.V(2)); } void Translate(float L) { Point3x D1=D*L; P+=D1; } }; GlTetramesh(CONT_TETRA * _t):tetra(_t){} GlTetramesh( ) {} CONT_TETRA * tetra; ClipPlane section; private: ScalarType shrink_factor; public: void SetHint(Hint h, double value){ switch(h){ case HShrinkFactor: shrink_factor = value; break; } } void AddClipSection(Point3x p0,Point3x p1,Point3x p2) { section=ClipPlane(p0,p1,p2); section.active=true; } void ClearClipSection() { section.active=false; } typedef Color4b (*color_func_vertex)(VertexType&v); color_func_vertex color_vertex; typedef Color4b (*color_func_tetra)(TetraType&v); color_func_tetra color_tetra; template void Draw(){ switch (dm){ case DMNone: break; case DMSmallTetra:_DrawSmallTetra();break; case DMFlat:_DrawSurface();break; case DMWire:_DrawSurface();break; case DMHidden:_DrawSurface();break; case DMFlatWire:_DrawFlatWire(); break; case DMTransparent:break; } } private: template void _DrawSmallTetra(){ Point3x p[4],br; typename CONT_TETRA::iterator it; glPushAttrib(0xffffffff); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glPolygonMode(GL_FRONT,GL_FILL); if (section.active) { section.GlClip(); section.GlDraw(); } /*glBegin(GL_TRIANGLES);*/ for( it = tetra->begin(); it != tetra->end(); ++it) if((!it->IsD())&&(!(it->IsS()))) //draw as normal { _DrawSmallTetra(*it); } else if((!it->IsD())&&((it->IsS())))//draw in selection mode { _DrawSelectedTetra(*it); } //glEnd(); glPopAttrib(); } template void _DrawFlatWire(){ glPushAttrib(0xffff); glEnable(GL_COLOR_MATERIAL); glEnable(GL_DEPTH); glDepthRange(0.001,1.0); Draw(); glDisable(GL_LIGHTING); glColor3f(0.0,0.0,0.0); glDepthRange(0.0,0.999); Draw(); glPopAttrib(); } template void _DrawSurface(){ typename CONT_TETRA::iterator it; glPushAttrib(0xffff); glEnable(GL_COLOR_MATERIAL); if((dm == DMWire)||(dm ==DMHidden)) { glDisable(GL_LIGHTING); glDisable(GL_NORMALIZE); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); } else { glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glPolygonMode(GL_FRONT,GL_FILL); } //glBegin(GL_TRIANGLES); for( it = tetra->begin(); it != tetra->end(); ++it) _DrawTetra((*it)); //glEnd(); glPopAttrib(); } void _DrawSelectedTetra(TetraType &t) { glPushMatrix(); glPushAttrib(0xffff); glDisable(GL_CLIP_PLANE0); glDisable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_NORMALIZE); glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glColor3d(1,0,0); glBegin(GL_TRIANGLES); for (int face=0;face<4;face++) { glVertex(t.V(Tetra::VofF(face,0))->P()); glVertex(t.V(Tetra::VofF(face,1))->P()); glVertex(t.V(Tetra::VofF(face,2))->P()); } glEnd(); //end drawing glPopAttrib(); glPopMatrix(); } template void _DrawTetra(TetraType &t) { if((!t.IsD())&&(!t.IsS())) { if ((dm!=DMWire)&&(dm!=DMHidden)) _ChooseColorTetra(t); for(int i = 0; i < 4; ++i){ if (dm == DMWire) _DrawFace(t,i); else { if (t.IsBorderF(i)) { if(nm==NMSmooth) _DrawFaceSmooth(t,i); else if(nm==NMFlat) _DrawFace(t,i); } } } } else if((!t.IsD())&&(t.IsS())) _DrawSelectedTetra(t); } template void _ChooseColorTetra(TetraType &t) { if (cm==CMNone) { if (t.IsS()) glColor3d(1,0,0); else glColor3d(0.8f,0.8f,0.8f); } else if(cm == CMPerTetraF) { Color4b c; c = color_tetra(t); GLint ic[4]; ic[0] = c[0];ic[1] = c[1];ic[2] = c[2];ic[3] = c[3]; glMaterialiv(GL_FRONT,GL_DIFFUSE ,ic); } } template void _ChooseColorVertex(VertexType &v) { if (cm!=CMNone) { if(cm == CMPerVertexF) { Color4b c; c = color_vertex(v); GLint ic[4]; ic[0] = c[0];ic[1] = c[1];ic[2] = c[2];ic[3] = c[3]; glMaterialiv(GL_FRONT,GL_DIFFUSE ,ic); } else if(cm == CMPerVertex) glColor3f(v.C()[0],v.C()[1],v.C()[2]); } } template void _DrawFaceSmooth(TetraType &t,int face) { VertexType *v0=t.V(Tetra::VofF(face,0)); VertexType *v1=t.V(Tetra::VofF(face,1)); VertexType *v2=t.V(Tetra::VofF(face,2)); glBegin(GL_TRIANGLES); _ChooseColorVertex(*v0); glNormal(v0->N()); glVertex(v0->P()); _ChooseColorVertex(*v1); glNormal(v1->N()); glVertex(v1->P()); _ChooseColorVertex(*v2); glNormal(v2->N()); glVertex(v2->P()); glEnd(); } template void _DrawFace(TetraType &t,int face) { glBegin(GL_TRIANGLES); glNormal(t.N(face)); VertexType *v0=t.V(Tetra::VofF(face,0)); VertexType *v1=t.V(Tetra::VofF(face,1)); VertexType *v2=t.V(Tetra::VofF(face,2)); _ChooseColorVertex(*v0); glVertex(v0->P()); _ChooseColorVertex(*v1); glVertex(v1->P()); _ChooseColorVertex(*v2); glVertex(v2->P()); glEnd(); } template void _DrawSmallTetra(TetraType &t) { Tetra3 T=Tetra3(); T.P0(0)=t.V(0)->cP(); T.P1(0)=t.V(1)->cP(); T.P2(0)=t.V(2)->cP(); T.P3(0)=t.V(3)->cP(); Point3x p[4], br; br=T.ComputeBarycenter(); for(int i = 0; i < 4; ++i) p[i] = t.V(i)->P()* shrink_factor + br *(1- shrink_factor); _ChooseColorTetra(t); glBegin(GL_TRIANGLES); for(int i = 0; i < 4; ++i) { glNormal(t.N(i)); VertexType *v0=t.V(Tetra::VofF(i,0)); VertexType *v1=t.V(Tetra::VofF(i,1)); VertexType *v2=t.V(Tetra::VofF(i,2)); _ChooseColorVertex(*v0); glVertex(p[Tetra::VofF(i,0)]); _ChooseColorVertex(*v1); glVertex(p[Tetra::VofF(i,1)]); _ChooseColorVertex(*v2); glVertex(p[Tetra::VofF(i,2)]); } glEnd(); } }; } // end namespace tetra } // end nemaspace tri #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/shot.h0000644000175000017500000001717011645601731017037 0ustar gladkgladk/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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.12 2006/12/18 16:02:57 matteodelle minor eroor correction on variable names Revision 1.11 2006/12/18 15:26:24 callieri added a function to approximate a far plane value given a shot and the mesh bbox Revision 1.10 2006/12/18 14:28:07 matteodelle *** empty log message *** Revision 1.9 2006/12/18 09:46:39 callieri camera+shot revamp: changed field names to something with more sense, cleaning of various functions, correction of minor bugs/incongruences, removal of the infamous reference in shot. Revision 1.8 2006/01/11 16:06:25 matteodelle *** empty log message *** Revision 1.8 2005/01/11 17:06:30 dellepiane FromTrackball() coorected (similarity->Extrinsics Revision 1.7 2005/11/25 10:33:33 spinelli shot.camera -> shot.Intrinsics shot.similarity.Matrix() -> shot.Extrinsics.Matrix() Revision 1.6 2005/02/22 11:15:01 ganovelli added vcg namespace Revision 1.5 2005/02/11 11:43:09 tommyfranken FromTrackball() corrected Revision 1.4 2004/12/15 18:45:06 tommyfranken *** empty log message *** Revision 1.3 2004/11/03 09:41:57 ganovelli added FromTrackball and fixed include names (Poiint to point) Revision 1.2 2004/10/05 19:04:45 ganovelli changed from classes to functions Revision 1.1 2004/09/15 22:59:13 ganovelli creation Revision 1.2 2004/09/06 21:41:30 ganovelli *** empty log message *** Revision 1.1 2004/09/03 13:01:51 ganovelli creation ****************************************************************************/ #ifndef __VCGLIB_GLSHOT #define __VCGLIB_GLSHOT // include vcg stuff #include #include #include #include // include wrap stuff #include #include #include template struct GlShot { typedef typename ShotType::ScalarType ScalarType; typedef GlCamera GlCameraType; /// returns the OpenGL 4x4 MODELVIEW matrix that describes the shot position and orientation (extrinsics) static void MatrixGL(ShotType & shot,vcg::Matrix44 & m) { m = shot.GetWorldToExtrinsicsMatrix(); } /// set the OpenGL MODELVIEW matrix to match the shot (extrinsics) static void TransformGL(vcg::Shot & shot) { vcg::Matrix44 m; MatrixGL(shot,m); glMultMatrix(m); } /// set the OpenGL PROJECTION and MODELVIEW matrix to match camera+shot. requires near and far plane static void SetView(vcg::Shot & shot, ScalarType nearDist, ScalarType farDist) { assert(glGetError() == 0); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); assert(glGetError() == 0); GlCameraType::TransformGL(shot.Intrinsics, nearDist, farDist); // apply camera/projection transformation assert(glGetError() == 0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); GlShot::TransformGL(shot); // apply similarity/modelview transformation assert(glGetError() == 0); } /// restore the previous OpenGL modelview and projection state. to be called AFTER a SetView static void UnsetView() { glPushAttrib(GL_TRANSFORM_BIT); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); } /// given a shot and the mesh bounding box, returns an approximate far plane distance /// distance is always approximated by excess static ScalarType GetFarPlane(vcg::Shot & shot, vcg::Box3 bbox) { ScalarType farDist; vcg::Point3 farcorner; vcg::Point3 campos = shot.Extrinsics.Tra(); if (abs(campos.X() - bbox.max.X()) > abs(campos.X() - bbox.min.X())) farcorner.X() = bbox.max.X(); else farcorner.X() = bbox.min.X(); if (abs(campos.Y() - bbox.max.Y()) > abs(campos.Y() - bbox.min.Y())) farcorner.Y() = bbox.max.Y(); else farcorner.Y() = bbox.min.Y(); if (abs(campos.Z() - bbox.max.Z()) > abs(campos.Z() - bbox.min.Z())) farcorner.Z() = bbox.max.Z(); else farcorner.Z() = bbox.min.Z(); farDist = (campos - farcorner).Norm(); return farDist; } /// given a shot and the mesh bounding box, return near and far plane (exact) static void GetNearFarPlanes(vcg::Shot & shot, vcg::Box3 bbox, ScalarType &nr, ScalarType &fr) { vcg::Point3 zaxis = shot.Axis(2); ScalarType offset = zaxis * shot.GetViewPoint(); bool first = true; for(int i = 0; i < 8; i++) { vcg::Point3 c = bbox.P(i); ScalarType d = -(zaxis * c - offset); if(first || d < nr) nr = d; if(first || d > fr) fr = d; first = false; } } static void SetSubView(vcg::Shot & shot, vcg::Point2 p1, vcg::Point2 p2) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); assert(glGetError() == 0); GlCameraType::SetSubView(shot.Intrinsics,p1,0,1000,p2); assert(glGetError() == 0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); GlShot::TransformGL(shot); // apply similarity/modelview transformation assert(glGetError() == 0); } /********************************** DEFINE SHOT FROM TRACKBALL Adds to a given shot the trackball transformations. After this operation the trackball should be resetted, to avoid multiple apply of the same transformation. ***********************************/ static void FromTrackball(const vcg::Trackball & tr, vcg::Shot & sShot, vcg::Shot & shot ) { vcg::Point3 cen; cen.Import(tr.center); vcg::Point3 tra; tra.Import(tr.track.tra); vcg::Matrix44 trM; trM.FromMatrix(tr.track.Matrix()); vcg::Point3 vp = Inverse(trM)*(sShot.GetViewPoint()-cen) +cen;// +tra; shot.SetViewPoint(vp); shot.Extrinsics.SetRot(sShot.Extrinsics.Rot()*trM); // shot.Extrinsics.sca = sShot.Extrinsics.sca*(ScalarType)tr.track.sca; } }; #endif meshlab-1.3.2+dfsg1/vcglib/wrap/gl/picking.h0000644000175000017500000001220311761424115017474 0ustar gladkgladk#pragma once /**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004 \/)\/ * * 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. * * * ****************************************************************************/ /**************************************************************************** This file contains two function providing the standard way to do picking using opendgl: - using the SELECT mode (first function) - using the depth buffer and gluUnproject (second function) History $Log: not supported by cvs2svn $ Revision 1.5 2007/05/21 13:22:40 cignoni Corrected gcc compiling issues Revision 1.4 2006/10/27 08:55:15 fiorin Added type cast (in order to remove warnings) Revision 1.3 2006/02/28 13:25:48 ponchio for(ii... -> for(int ii Revision 1.2 2006/02/13 13:06:34 cignoni Removed glut. Added ifdef guards and namespace. Added bool return value to the pick function Revision 1.1 2005/12/03 09:36:28 ganovelli *** empty log message *** ****************************************************************************/ #ifndef WRAP_GL_PICKING_H #define WRAP_GL_PICKING_H #include #ifndef GLU_VERSIONS #ifdef __APPLE__ #include #else #ifdef _WIN32 #include #endif #include #endif #endif namespace vcg { template int Pick( const int & x, const int &y, TO_PICK_CONT_TYPE &m, std::vector &result, void (draw_func)(typename TO_PICK_CONT_TYPE::value_type &), int width=4, int height=4) { result.clear(); long hits; int sz = int(m.size())*5; GLuint *selectBuf =new GLuint[sz]; glSelectBuffer(sz, selectBuf); glRenderMode(GL_SELECT); glInitNames(); /* Because LoadName() won't work with no names on the stack */ glPushName(-1); double mp[16]; GLint viewport[4]; glGetIntegerv(GL_VIEWPORT,viewport); glPushAttrib(GL_TRANSFORM_BIT); glMatrixMode(GL_PROJECTION); glGetDoublev(GL_PROJECTION_MATRIX ,mp); glPushMatrix(); glLoadIdentity(); //gluPickMatrix(x, viewport[3]-y, 4, 4, viewport); gluPickMatrix(x, y, width, height, viewport); glMultMatrixd(mp); glMatrixMode(GL_MODELVIEW); glPushMatrix(); int cnt=0; typename TO_PICK_CONT_TYPE::iterator ei; for(ei=m.begin();ei!=m.end();++ei) { glLoadName(cnt); draw_func(*ei); cnt++; } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); hits = glRenderMode(GL_RENDER); if (hits <= 0) return 0; std::vector< std::pair > H; for(int ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); } std::sort(H.begin(),H.end()); result.resize(H.size()); for(int ii=0;ii bool Pick(const int & x, const int &y, PointType &pp){ double res[3]; GLdouble mm[16],pm[16]; GLint vp[4]; glGetDoublev(GL_MODELVIEW_MATRIX,mm); glGetDoublev(GL_PROJECTION_MATRIX,pm); glGetIntegerv(GL_VIEWPORT,vp); float pix; glReadPixels(x,y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&pix); GLfloat depthrange[2]={0,0}; glGetFloatv(GL_DEPTH_RANGE,depthrange); if(pix==depthrange[1]) return false; gluUnProject(x,y,pix,mm,pm,vp,&res[0],&res[1],&res[2]); pp=PointType (res[0],res[1],res[2]); return true; } } // end namespace #endif meshlab-1.3.2+dfsg1/vcglib/wrap/system/0000755000175000017500000000000012227522351016622 5ustar gladkgladkmeshlab-1.3.2+dfsg1/vcglib/wrap/system/qgetopt.cpp0000644000175000017500000002306311732414757021027 0ustar gladkgladk/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * 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. * * * ****************************************************************************/ #include #include #include #include "qgetopt.h" #include using namespace std; GetOpt::GetOpt(int argc, char *argv[] ) { appname = argv[0]; for(int i = 1; i < argc; i++) args.push_back(argv[i]); } GetOpt::GetOpt(const QStringList &a): args(a) { appname = a[0]; args = a; args.pop_front(); } //add an option without a value void GetOpt::addSwitch(char s, const QString &name, const QString &description, bool *b ) { Option option; assert(!findOption(s, option)); assert(!findArg(name, option)); option.type = Option::SWITCH; option.o = s; option.name = name; option.description = description; option.b = b; options.push_back(option); } //add a valued option (v will be left untouched if the option is not given) void GetOpt::addOption(char s, const QString &name, const QString &description, QVariant *v ) { Option option; assert(!findOption(s, option)); assert(!findArg(name, option)); option.type = Option::OPTION; option.o = s; option.name = name; option.description = description; option.value = v; options.push_back(option); } //add an argument void GetOpt::addArgument(const QString &name, const QString &description, QVariant *v) { Option option; assert(!findArg(name, option)); option.type = Option::ARGUMENT; option.name = name; option.description = description; option.value = v; options.push_back(option); } //add an optional agrument void GetOpt::addOptionalArgument(const QString &name, const QString &description, QVariant *v) { Option option; assert(!findArg(name, option)); option.type = Option::OPTIONAL; option.name = name; option.description = description; option.value = v; options.push_back(option); } //return application name QString &GetOpt::applicationName() { return appname; } //return usage string QString GetOpt::usage() { QString u = "Usage: " + appname; //arguments bool has_optionals = false; bool has_options = false; for(int i = 0; i < options.size(); i++) { if(options[i].type == Option::OPTION) has_options = true; if(options[i].type == Option::OPTIONAL) has_optionals = true; if(options[i].type != Option::ARGUMENT) continue; u += " <" + options[i].name + ">"; } //optional arguments if(has_optionals) { u += " ["; for(int i = 0; i < options.size(); i++) { if(options[i].type != Option::OPTIONAL) continue; u += "<" + options[i].name + ">"; } u += "]"; } if(has_options) { u += " [-"; for(int i = 0; i < options.size(); i++) { if(options[i].type != Option::OPTION) continue; u += options[i].o; } u += "]"; } u += "\n\n"; //compute maxlen: int maxlen = 0; for(int i = 0; i < options.size(); i++) { Option &o = options[i]; int len = o.name.size() + 2; switch(o.type) { case Option::ARGUMENT: case Option::OPTIONAL: break; case Option::SWITCH: len += 5; break; case Option::OPTION: len += 16; break; default: break; } if(len > maxlen) maxlen = len; } //print options and arguments in the given order for(int i = 0; i < options.size(); i++) { Option &o = options[i]; QString line = ""; switch(o.type) { case Option::ARGUMENT: case Option::OPTIONAL: line += o.name; break; case Option::SWITCH: line += "-" + QString(o.o) + " --" + o.name; break; case Option::OPTION: line += "-" + QString(o.o) + " --" + o.name + " "; break; default: break; } QString blank = ""; blank.resize(maxlen - line.size()); blank.fill(' '); line += blank + formatDesc(o.description, maxlen) + "\n"; u += line; } return u; } void GetOpt::parse() { QString error; if(!parse(error)) { cerr << qPrintable(error) << endl << endl << qPrintable(usage()) << endl << endl; exit(0); } } bool GetOpt::parse(QString &error) { for(int i = 0; i < args.size(); i++) { QString arg = args[i]; if(args[i] == "-h" || args[i] == "--help") { cout << qPrintable(usage()) << endl << qPrintable(help) << endl; exit(0); } //long option if(arg.startsWith( QString::fromLatin1( "--" ) ) ) { arg = arg.mid( 2 ); if(arg.isEmpty()) { error = "'--' feature not supported, yet"; return false; } Option o; if(!findArg(arg, o)) { error = "Unknown option: '" + arg + "'"; return false; } if(o.type == Option::SWITCH) { *(o.b) = true; } else { //OPTION i++; if(args.size() <= i) { error = "Missing value for option: " + arg; return false; } arg = args[i]; if(i == args.size() || arg[0] == '-') { error = "Missing argument after option '" + arg + "'"; return false; } QVariant v(arg); if(!v.canConvert(o.value->type()) || !v.convert(o.value->type())) { error = "Error while parsing option " + o.name + ": cannot convert " + arg + " to: " + o.value->typeName(); return false; } *(o.value) = v; } //option } else if( arg[0] == '-' ) { if(arg.size() != 2) { error = "Invalid option: " + arg; return false; } Option o; if(!findOption(arg[1].toAscii(), o)) { error = "Unknown option: '" + arg + "'"; return false; } if(o.type == Option::SWITCH) { *(o.b) = true; } else { //OPTION i++; if(args.size() <= i) { error = "Missing value for option: " + arg; return false; } arg = args[i]; if(i == args.size()) { error = "Missing argument after option '" + arg + "'"; return false; } QVariant v(arg); if(!v.canConvert(o.value->type()) || !v.convert(o.value->type())) { error = "Error while parsing option " + o.name + ": cannot convert " + arg + " to: " + o.value->typeName(); return false; } *(o.value) = v; } //argument } else { arguments.push_back(arg); } } //test arguments for(int i = 0; i < options.size(); i++) { Option &o = options[i]; if(o.type != Option::ARGUMENT) continue; if(arguments.isEmpty()) { error = "Too few arguments, could not parse argument '" + o.name + "'"; return false; } *(o.value) = arguments.front(); arguments.pop_front(); } //test arguments for(int i = 0; i < options.size(); i++) { Option &o = options[i]; if(o.type != Option::OPTIONAL) continue; if(arguments.isEmpty()) break; *(o.value) = arguments.front(); arguments.pop_front(); } //test arguments for(int i = 0; i < options.size(); i++) { Option &o = options[i]; if(o.type != Option::ARGUMENT) continue; if(arguments.isEmpty()) break; *(o.value) = arguments.front(); arguments.pop_front(); } if(!arguments.isEmpty() && !unlimitedArgs) { error = "Too many arguments"; return false; } return true; } bool GetOpt::findOption(char c, Option &option) { for(int i = 0; i < options.size(); i++) { Option &o = options[i]; if(o.type != Option::OPTION && o.type != Option::SWITCH) continue; if(o.o == c) { option = o; return true; } } return false; } bool GetOpt::findArg(const QString &name, Option &option) { for(int i = 0; i < options.size(); i++) { Option &o = options[i]; if(o.name == name) { option = o; return true; } } return false; } QString GetOpt::formatDesc(QString desc, int len) { QString output; //search for last space before 79 - len characters while(!desc.isEmpty()) { int pos = desc.lastIndexOf(" ", 79 - len); if(pos == -1) { output += desc; break; } output += desc.left(pos) + "\n"; QString blank; blank.resize(len); blank.fill(' '); output += blank; desc = desc.mid(pos+1); } return output; } meshlab-1.3.2+dfsg1/vcglib/wrap/system/qgetopt.h0000644000175000017500000001015111517500604020452 0ustar gladkgladk/**************************************************************************** * MeshLab o o * * An extendible mesh processor o o * * _ O _ * * Copyright(C) 2005, 2009 \/)\/ * * 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. * * * ****************************************************************************/ #ifndef GETOPT_H #define GETOPT_H #include #include #include #include /* Example usage: QString file1, file2; QString o_gamma = "10"; QString o_scale = "0.7"; GetOpt opt(argc, argv); opt.addArgument("img1", "first image", &file1); opt.addArgument("img2", "second image", &file2); opt.addOption('g', "gamma", "weigth to derivatives of images (default: 10)", &o_gamma); opt.addOption('s', "scale", "scale [0.5-0.99] for multiscale approach (default: 0.7)", &o_scale); opt.parse(); */ class GetOpt { protected: struct Option { enum Type { SWITCH, OPTION, ARGUMENT, OPTIONAL }; Type type; char o; QString name; QString description; QVariant *value; bool *b; }; bool unlimitedArgs; QList