From ab22877d1dbd31b9016dd1d124cfb05817633d57 Mon Sep 17 00:00:00 2001 From: cignoni Date: Wed, 21 Sep 2005 10:29:33 +0000 Subject: [PATCH] Initial Relase --- apps/sample/sample.pro | 15 + apps/sample/sample.sln | 51 +++ apps/sample/space_minimal/space_minimal.cpp | 42 +++ apps/sample/space_minimal/space_minimal.pro | 11 + apps/sample/trimesh_SDL/mesh_type.h | 26 ++ apps/sample/trimesh_SDL/mysdl.h | 299 ++++++++++++++++++ apps/sample/trimesh_SDL/trimesh_sdl.cpp | 85 +++++ apps/sample/trimesh_SDL/trimesh_sdl.pro | 16 + apps/sample/trimesh_base/trimesh_base.cpp | 44 +++ apps/sample/trimesh_base/trimesh_base.pro | 11 + .../trimesh_isosurface/trimesh_isosurface.cpp | 146 +++++++++ .../trimesh_isosurface/trimesh_isosurface.pro | 18 ++ .../trimesh_isosurface/trivial_walker.h | 224 +++++++++++++ apps/sample/trimesh_refine/trimesh_refine.cpp | 90 ++++++ apps/sample/trimesh_refine/trimesh_refine.pro | 13 + apps/sample/trimesh_smooth/trimesh_smooth.cpp | 51 +++ apps/sample/trimesh_smooth/trimesh_smooth.pro | 11 + .../trimesh_topology/trimesh_topology.cpp | 82 +++++ .../trimesh_topology/trimesh_topology.pro | 11 + 19 files changed, 1246 insertions(+) create mode 100644 apps/sample/sample.pro create mode 100644 apps/sample/sample.sln create mode 100644 apps/sample/space_minimal/space_minimal.cpp create mode 100644 apps/sample/space_minimal/space_minimal.pro create mode 100644 apps/sample/trimesh_SDL/mesh_type.h create mode 100644 apps/sample/trimesh_SDL/mysdl.h create mode 100644 apps/sample/trimesh_SDL/trimesh_sdl.cpp create mode 100644 apps/sample/trimesh_SDL/trimesh_sdl.pro create mode 100644 apps/sample/trimesh_base/trimesh_base.cpp create mode 100644 apps/sample/trimesh_base/trimesh_base.pro create mode 100644 apps/sample/trimesh_isosurface/trimesh_isosurface.cpp create mode 100644 apps/sample/trimesh_isosurface/trimesh_isosurface.pro create mode 100644 apps/sample/trimesh_isosurface/trivial_walker.h create mode 100644 apps/sample/trimesh_refine/trimesh_refine.cpp create mode 100644 apps/sample/trimesh_refine/trimesh_refine.pro create mode 100644 apps/sample/trimesh_smooth/trimesh_smooth.cpp create mode 100644 apps/sample/trimesh_smooth/trimesh_smooth.pro create mode 100644 apps/sample/trimesh_topology/trimesh_topology.cpp create mode 100644 apps/sample/trimesh_topology/trimesh_topology.pro diff --git a/apps/sample/sample.pro b/apps/sample/sample.pro new file mode 100644 index 00000000..b90365e2 --- /dev/null +++ b/apps/sample/sample.pro @@ -0,0 +1,15 @@ +###################################################################### +# Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 +###################################################################### + +TEMPLATE = subdirs +SUBDIRS = trimesh_base \ + trimesh_topology\ + trimesh_smooth \ + trimesh_refine \ + trimesh_isosurface \ + trimesh_SDL + +sources.files = *.pro +sources.path = . +INSTALLS += sources diff --git a/apps/sample/sample.sln b/apps/sample/sample.sln new file mode 100644 index 00000000..3cd63c29 --- /dev/null +++ b/apps/sample/sample.sln @@ -0,0 +1,51 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trimesh_base", "trimesh_base\trimesh_base.vcproj", "{0B7F680B-ED20-3001-B9BE-1EDAFE545C64}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trimesh_topology", "trimesh_topology\trimesh_topology.vcproj", "{627E5101-FB98-3026-850E-BAF0DD88A5CE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trimesh_smooth", "trimesh_smooth\trimesh_smooth.vcproj", "{1F2E5C6D-8394-3AC5-83F4-C2947B31B607}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trimesh_refine", "trimesh_refine\trimesh_refine.vcproj", "{831831A5-C915-3439-8BD1-CA15B529BDB3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trimesh_isosurface", "trimesh_isosurface\trimesh_isosurface.vcproj", "{A52CB564-AC7F-34E5-90E5-07F879D5DD3D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trimesh_sdl", "trimesh_SDL\trimesh_sdl.vcproj", "{637DBA16-5309-3D1C-B69B-27A5E4EA737B}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {0B7F680B-ED20-3001-B9BE-1EDAFE545C64}.Debug.ActiveCfg = Debug|Win32 + {0B7F680B-ED20-3001-B9BE-1EDAFE545C64}.Debug.Build.0 = Debug|Win32 + {0B7F680B-ED20-3001-B9BE-1EDAFE545C64}.Release.ActiveCfg = Release|Win32 + {0B7F680B-ED20-3001-B9BE-1EDAFE545C64}.Release.Build.0 = Release|Win32 + {627E5101-FB98-3026-850E-BAF0DD88A5CE}.Debug.ActiveCfg = Debug|Win32 + {627E5101-FB98-3026-850E-BAF0DD88A5CE}.Debug.Build.0 = Debug|Win32 + {627E5101-FB98-3026-850E-BAF0DD88A5CE}.Release.ActiveCfg = Release|Win32 + {627E5101-FB98-3026-850E-BAF0DD88A5CE}.Release.Build.0 = Release|Win32 + {1F2E5C6D-8394-3AC5-83F4-C2947B31B607}.Debug.ActiveCfg = Debug|Win32 + {1F2E5C6D-8394-3AC5-83F4-C2947B31B607}.Debug.Build.0 = Debug|Win32 + {1F2E5C6D-8394-3AC5-83F4-C2947B31B607}.Release.ActiveCfg = Release|Win32 + {1F2E5C6D-8394-3AC5-83F4-C2947B31B607}.Release.Build.0 = Release|Win32 + {831831A5-C915-3439-8BD1-CA15B529BDB3}.Debug.ActiveCfg = Debug|Win32 + {831831A5-C915-3439-8BD1-CA15B529BDB3}.Debug.Build.0 = Debug|Win32 + {831831A5-C915-3439-8BD1-CA15B529BDB3}.Release.ActiveCfg = Release|Win32 + {831831A5-C915-3439-8BD1-CA15B529BDB3}.Release.Build.0 = Release|Win32 + {A52CB564-AC7F-34E5-90E5-07F879D5DD3D}.Debug.ActiveCfg = Debug|Win32 + {A52CB564-AC7F-34E5-90E5-07F879D5DD3D}.Debug.Build.0 = Debug|Win32 + {A52CB564-AC7F-34E5-90E5-07F879D5DD3D}.Release.ActiveCfg = Release|Win32 + {A52CB564-AC7F-34E5-90E5-07F879D5DD3D}.Release.Build.0 = Release|Win32 + {637DBA16-5309-3D1C-B69B-27A5E4EA737B}.Debug.ActiveCfg = Debug|Win32 + {637DBA16-5309-3D1C-B69B-27A5E4EA737B}.Debug.Build.0 = Debug|Win32 + {637DBA16-5309-3D1C-B69B-27A5E4EA737B}.Release.ActiveCfg = Release|Win32 + {637DBA16-5309-3D1C-B69B-27A5E4EA737B}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal \ No newline at end of file diff --git a/apps/sample/space_minimal/space_minimal.cpp b/apps/sample/space_minimal/space_minimal.cpp new file mode 100644 index 00000000..f4c44140 --- /dev/null +++ b/apps/sample/space_minimal/space_minimal.cpp @@ -0,0 +1,42 @@ +#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; +} \ No newline at end of file diff --git a/apps/sample/space_minimal/space_minimal.pro b/apps/sample/space_minimal/space_minimal.pro new file mode 100644 index 00000000..1cd50330 --- /dev/null +++ b/apps/sample/space_minimal/space_minimal.pro @@ -0,0 +1,11 @@ +###################################################################### +# 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 diff --git a/apps/sample/trimesh_SDL/mesh_type.h b/apps/sample/trimesh_SDL/mesh_type.h new file mode 100644 index 00000000..eb32afcb --- /dev/null +++ b/apps/sample/trimesh_SDL/mesh_type.h @@ -0,0 +1,26 @@ +#ifndef __MYMESH +#define __MYMESH + +#include + +// stuff to define the mesh +#include +#include +#include +#include +// the trackball +#include + +class MyFace; +class MyEdge; +class MyVertex:public vcg::VertexAFVMVNVQ{ +public: vcg::Point3f tx,ty; +} ; +class MyFace:public vcg::FaceAFAVFNFQ { +public: + int * r; // belongs to region r + int ip; // which plane of r +}; +class MyMesh: public vcg::tri::TriMesh< std::vector, std::vector >{}; + +#endif \ No newline at end of file diff --git a/apps/sample/trimesh_SDL/mysdl.h b/apps/sample/trimesh_SDL/mysdl.h new file mode 100644 index 00000000..9ae150fa --- /dev/null +++ b/apps/sample/trimesh_SDL/mysdl.h @@ -0,0 +1,299 @@ +/**************************************************************************** + * 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/03/15 07:00:54 ganovell +*** empty log message *** + + +****************************************************************************/ + +#include +#include + + +#include + +#include +#include +#include + + +#ifdef _SHOW_A_MESH +// the trimesh drawer +#include "mesh_type.h" +#include +#endif //_SHOW_A_MESH + +#include + +bool fullscreen = false, quit = false,keepdrawing = true; +int width =1024; +int height = 768; +int x,y; + +vcg::GlTrimesh glWrap; +int drawMode; +int keypress; +int pic_x,pic_y,doPick; +float sc; +MyMesh::FaceType * Pick(int x, int y, int width=4, int height=4); + +SDL_Surface *screen = NULL; +vcg::Trackball track; + +void gl_print(float x, float y, char *str); +bool init(const std::string &str) { + + if(SDL_Init(SDL_INIT_VIDEO) != 0) { + return false; + } + + const SDL_VideoInfo *info = SDL_GetVideoInfo(); + int bpp = info->vfmt->BitsPerPixel; + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + int flags = SDL_OPENGL; + if(fullscreen) + flags |= SDL_FULLSCREEN; + + screen = SDL_SetVideoMode(width, height, bpp, flags); + if(!screen) { + return false; + } + + SDL_WM_SetIcon(SDL_LoadBMP("inspector.bmp"), NULL); + SDL_WM_SetCaption(str.c_str(), str.c_str()); + + + glDisable(GL_DITHER); + glShadeModel(GL_SMOOTH); + glHint( GL_FOG_HINT, GL_NICEST ); + glEnable(GL_DEPTH_TEST); + glDepthFunc( GL_LEQUAL ); + glDisable(GL_LIGHTING); + + glEnableClientState(GL_VERTEX_ARRAY); + + #ifdef _SHOW_A_MESH + glWrap.Update(); + #endif + return true; +} + + +void display(){ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + 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); + + glViewport(0,0,width,height); + + track.GetView(); + track.Apply(); + track.Draw(); + + +#ifdef _SHOW_A_MESH + glScalef(1-sc,1-sc,1-sc); + 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 + MyMesh::FaceType* fp=NULL; + if(doPick) + { + fp = Pick(pic_x,pic_y,1,1); + doPick=false; + } + + // the trimesh drawing calls + switch(drawMode) + { + case 0: glWrap.Draw ();break; + case 1: glWrap.Draw (); break; + case 2: glWrap.Draw ();break; + case 3: glWrap.Draw ();break; + case 4: glWrap.Draw ();break; + case 5: glWrap.Draw ();break; + case 6: break; + } +#endif + +// glScalef(scale, scale, scale); + // Point3f center = sphere.Center(); + // glTranslatef(-center[0], -center[1], -center[2]); + + SDL_GL_SwapBuffers(); +} + + +int sdl_idle() { + + SDL_Event event; + while( !quit ) { + unsigned int anything = SDL_PollEvent(&event); + if(!anything && !keepdrawing) { + SDL_WaitEvent(&event); + anything = true; + } + if(anything) { + switch( event.type ) { + case SDL_QUIT: quit = 1; break; + case SDL_KEYDOWN: + switch(event.key.keysym.sym) { + case SDLK_RCTRL: + case SDLK_LCTRL: track.ButtonDown(vcg::Trackball::KEY_CTRL); break; + case SDLK_q: exit(0); break; + } + break; + case SDL_KEYUP: + switch(event.key.keysym.sym) { + case SDLK_RCTRL: + case SDLK_LCTRL: + track.ButtonUp(vcg::Trackball::KEY_CTRL); break; + } + break; + case SDL_MOUSEBUTTONDOWN: + x = event.button.x; + y = height - event.button.y; + +#ifdef SDL_BUTTON_WHEELUP + if(event.button.button == SDL_BUTTON_WHEELUP) + track.MouseWheel(1); + else if(event.button.button == SDL_BUTTON_WHEELDOWN) + track.MouseWheel(-1); + else +#endif + + if(event.button.button == SDL_BUTTON_LEFT) + track.MouseDown(x, y, vcg::Trackball::BUTTON_LEFT); + else if(event.button.button == SDL_BUTTON_RIGHT) + track.MouseDown(x, y, vcg::Trackball::BUTTON_RIGHT); + break; + case SDL_MOUSEBUTTONUP: + x = event.button.x; + y = height - event.button.y; + if(event.button.button == SDL_BUTTON_LEFT) + track.MouseUp(x, y, vcg::Trackball::BUTTON_LEFT); + else if(event.button.button == SDL_BUTTON_RIGHT) + track.MouseUp(x, y, vcg::Trackball::BUTTON_RIGHT); + break; + case SDL_MOUSEMOTION: + while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK)); + x = event.motion.x; + y = height - event.motion.y; + track.MouseMove(x, y); + break; + case SDL_VIDEOEXPOSE: + default: break; + } + } + + display(); + } + + SDL_Quit(); + return -1; +} + +void gl_print(float x, float y, char *str) { + glRasterPos2f(x, y); + int len = (int)strlen(str); + for(int i = 0; i < len; i++) + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, str[i]); +} + +#ifdef _SHOW_A_MESH +// you can use this funcion replacing the face with your own pickable primitive + MyMesh::FaceType * Pick(int x, int y,int w,int h) +{ + long hits; + int sz=glWrap.m->face.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, viewport[3]-y, width, height, viewport); + glMultMatrixd(mp); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + int tricnt=0; + + MyMesh::FaceIterator ti; + for(ti=glWrap.m->face.begin();ti!=glWrap.m->face.end();++ti) + { + if(!(*ti).IsD()) + { + glLoadName(tricnt); + + glBegin(GL_TRIANGLES); + glVertex((*ti).P(0)); + glVertex((*ti).P(1)); + glVertex((*ti).P(2)); + glEnd(); + } + tricnt++; + } + + 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(int ii=0;ii(selectBuf[ii*4+1]/4294967295.0,selectBuf[ii*4+3])); + } + if(H.empty()) return NULL; + std::sort(H.begin(),H.end()); + + return (MyMesh::FaceType *)&glWrap.m->face[H[0].second]; + +} +#endif //_SHOW_A_MESH diff --git a/apps/sample/trimesh_SDL/trimesh_sdl.cpp b/apps/sample/trimesh_SDL/trimesh_sdl.cpp new file mode 100644 index 00000000..a6f35714 --- /dev/null +++ b/apps/sample/trimesh_SDL/trimesh_sdl.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** + * 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/03/15 07:00:54 ganovell +*** empty log message *** + + +****************************************************************************/ + +#include "mysdl.h" + +#ifdef _SHOW_A_MESH +// mesh definition +#include "mesh_type.h" +#include +#include +#include +#include +#endif //_SHOW_A_MESH + +int main(int argc, char *argv[]) { + int level = 0; + int apatch = -1; + float error = 4; + + vcg::Trackball track; +#ifdef _SHOW_A_MESH + // declare the mesh + MyMesh mesh; + MyMesh::VertexIterator vi; + + // load from disk + vcg::tri::io::ImporterPLY::Open(mesh,argv[1]); + + // update bounding box + vcg::tri::UpdateBounding::Box(mesh); + + // update bounding box + vcg::tri::UpdateNormals::PerVertex(mesh); + + glWrap.m = &mesh; +#endif //_SHOW_A_MESH + + + if(!init("SDL_minimal_viewer")) { + std::cerr << "Could not init SDL window\n"; + return -1; + } + + glClearColor(0, 0, 0, 0); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_NORMALIZE); + glEnable(GL_COLOR_MATERIAL); + glEnable(GL_CULL_FACE); + + sdl_idle(); + exit(0); +} + + + diff --git a/apps/sample/trimesh_SDL/trimesh_sdl.pro b/apps/sample/trimesh_SDL/trimesh_sdl.pro new file mode 100644 index 00000000..fc00f30a --- /dev/null +++ b/apps/sample/trimesh_SDL/trimesh_sdl.pro @@ -0,0 +1,16 @@ +###################################################################### +# Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 +###################################################################### + +TARGET = trimesh_sdl +DEFINES+= _SHOW_A_MESH +LIBPATH += ../../../../code/lib/SDL/lib +LIBPATH += ../../../../code/lib/glew/lib +win32:LIBS += SDL.lib SDLmain.lib opengl32.lib glu32.lib glew32s.lib glew32.lib +DEPENDPATH += . +INCLUDEPATH += . ../../.. +INCLUDEPATH += . ../../../../code/lib/glew/include +INCLUDEPATH += . ../../../../code/lib/SDL/include +CONFIG += console stl +TEMPLATE = app +SOURCES += trimesh_sdl.cpp ../../../wrap/ply/plylib.cpp ../../../wrap/gui/trackball.cpp ../../../wrap/gui/trackmode.cpp diff --git a/apps/sample/trimesh_base/trimesh_base.cpp b/apps/sample/trimesh_base/trimesh_base.cpp new file mode 100644 index 00000000..834c5688 --- /dev/null +++ b/apps/sample/trimesh_base/trimesh_base.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace vcg; +using namespace std; + +class AEdge; // dummy prototype never used +class AFace; +class AVertex : public vcg::Vertex< double,AEdge,AFace > {}; +class AFace : public vcg::FaceFCFN< AVertex,AEdge,AFace > {}; +class AMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; + +class CEdge; // dummy prototype never used +class CFace; +class CVertex : public vcg::VertexVN< double,CEdge,CFace > {}; +class CFace : public vcg::FaceFN< CVertex,CEdge,CFace > {}; +class CMesh : public vcg::tri::TriMesh< std::vector, std::vector > {}; + + +int main(int , char **) +{ + AMesh am; + CMesh cm; + tri::Tetrahedron(cm); + tri::Tetrahedron(am); + + 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 + tri::UpdateNormals::PerVertexPerFace(cm); + printf("Normal of face 0 is %f %f %f",cm.face[0].N()[0],cm.face[0].N()[1],cm.face[0].N()[2]); + + tri::UpdateNormals::PerFace(am); + + return 0; +} diff --git a/apps/sample/trimesh_base/trimesh_base.pro b/apps/sample/trimesh_base/trimesh_base.pro new file mode 100644 index 00000000..1cd50330 --- /dev/null +++ b/apps/sample/trimesh_base/trimesh_base.pro @@ -0,0 +1,11 @@ +###################################################################### +# 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 diff --git a/apps/sample/trimesh_isosurface/trimesh_isosurface.cpp b/apps/sample/trimesh_isosurface/trimesh_isosurface.cpp new file mode 100644 index 00000000..69076ff3 --- /dev/null +++ b/apps/sample/trimesh_isosurface/trimesh_isosurface.cpp @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include "trivial_walker.h" +#include +#include + +using namespace std; +using namespace vcg; + +#include +#include +#include +#include + +typedef float ScalarType; + +class MyEdge; +class MyFace; +class MyVertex : public vcg::Vertex< ScalarType, MyEdge, MyFace > {}; +class MyFace : public vcg::Face< MyVertex, MyEdge, MyFace> {}; +class MyMesh : public vcg::tri::TriMesh< std::vector< MyVertex>, std::vector< MyFace > > {}; + +template +class Volume +{ +public: + typedef VOX_TYPE VoxelType; + 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]]; + } + + +enum { XAxis=0,YAxis=1,ZAxis=2} VolumeAxis; + +template < class VertexPointerType, enum 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;}; +}; + + +typedef Volume 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*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"); +}; \ No newline at end of file diff --git a/apps/sample/trimesh_isosurface/trimesh_isosurface.pro b/apps/sample/trimesh_isosurface/trimesh_isosurface.pro new file mode 100644 index 00000000..94d5d3e0 --- /dev/null +++ b/apps/sample/trimesh_isosurface/trimesh_isosurface.pro @@ -0,0 +1,18 @@ +###################################################################### +# Automatically generated by qmake (2.00a) mer 6. lug 08:37:03 2005 +###################################################################### + +LIBPATH += +DEPENDPATH += . +INCLUDEPATH += . ../../.. +CONFIG += console stl +TEMPLATE = app +# Input +HEADERS += Definitions.h \ + Implicit.h \ + ImplicitSphere.h \ + SphereDifference.h \ + SphereUnion.h \ + Volume.h \ + Walker.h +SOURCES += trimesh_isosurface.cpp ../../../wrap/ply/plylib.cpp diff --git a/apps/sample/trimesh_isosurface/trivial_walker.h b/apps/sample/trimesh_isosurface/trivial_walker.h new file mode 100644 index 00000000..53e7e29b --- /dev/null +++ b/apps/sample/trimesh_isosurface/trivial_walker.h @@ -0,0 +1,224 @@ +#ifndef __VCG_TRIVIAL_WALKER +#define __VCG_TRIVIAL_WALKER + +namespace vcg { + namespace tri { + + +// La classe Walker implementa la politica di visita del volume; conoscendo l'ordine di visita del volume +// è conveniente che il Walker stesso si faccia carico del caching dei dati utilizzati durante l'esecuzione +// degli algoritmi MarchingCubes ed ExtendedMarchingCubes, in particolare il calcolo del volume ai vertici +// delle celle e delle intersezioni della superficie con le celle. In questo esempio il volume da processare +// viene suddiviso in fette; in questo modo se il volume ha dimensione h*l*w (rispettivamente altezza, +// larghezza e profondità), lo spazio richiesto per il caching dei vertici già allocati passa da O(h*l*w) +// a O(h*l). + +template +class TrivialWalker +{ +private: + typedef int VertexIndex; + typedef typename MeshType::ScalarType ScalarType; + typedef typename MeshType::VertexPointer VertexPointer; + public: + + // bbox is the portion of the volume to be computed + // resolution determine the sampling step: + // should be a divisor of bbox size (e.g. if bbox size is 256^3 resolution could be 128,64, etc) + + + void Init(VolumeType &volume) + { + _bbox = Box3i(Point3i(0,0,0),volume.ISize()); + _slice_dimension = _bbox.DimX()*_bbox.DimZ(); + + _x_cs = new VertexIndex[ _slice_dimension ]; + _y_cs = new VertexIndex[ _slice_dimension ]; + _z_cs = new VertexIndex[ _slice_dimension ]; + _x_ns = new VertexIndex[ _slice_dimension ]; + _z_ns = new VertexIndex[ _slice_dimension ]; + + }; + + ~TrivialWalker() + {_thr=0;} + + template + void BuildMesh(MeshType &mesh, VolumeType &volume, EXTRACTOR_TYPE &extractor, const float threshold) + { + Init(volume); + _volume = &volume; + _mesh = &mesh; + _mesh->Clear(); + _thr=threshold; + vcg::Point3i p1, p2; + + Begin(); + extractor.Initialize(); + for (int j=_bbox.min.Y(); j<(_bbox.max.Y()-1)-1; j+=1) + { if((j%10)==0) printf("Marching volume z %i (%i ..%i)\r",j,_bbox.min.Y(),_bbox.max.Y()); + + for (int i=_bbox.min.X(); i<(_bbox.max.X()-1)-1; i+=1) + { + for (int k=_bbox.min.Z(); k<(_bbox.max.Z()-1)-1; k+=1) + { + p1.X()=i; p1.Y()=j; p1.Z()=k; + p2.X()=i+1; p2.Y()=j+1; p2.Z()=k+1; + extractor.ProcessCell(p1, p2); + } + } + NextSlice(); + } + extractor.Finalize(); + _volume = NULL; + _mesh = NULL; + }; + + float V(int pi, int pj, int pk) + { + return _volume->Val(pi, pj, pk)-_thr; + } + + bool Exist(const vcg::Point3i &p0, const vcg::Point3i &p1, VertexPointer &v) + { + int pos = p0.X()+p0.Z()*_bbox.max.X(); + int vidx; + + if (p0.X()!=p1.X()) // punti allineati lungo l'asse X + vidx = (p0.Y()==_current_slice) ? _x_cs[pos] : _x_ns[pos]; + else if (p0.Y()!=p1.Y()) // punti allineati lungo l'asse Y + vidx = _y_cs[pos]; + else if (p0.Z()!=p1.Z()) // punti allineati lungo l'asse Z + vidx = (p0.Y()==_current_slice)? _z_cs[pos] : _z_ns[pos]; + else + assert(false); + + v = (vidx!=-1)? &_mesh->vert[vidx] : NULL; + return v!=NULL; + } + + void GetXIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointer &v) + { + int i = p1.X() - _bbox.min.X(); + int z = p1.Z() - _bbox.min.Z(); + VertexIndex index = i+z*_bbox.max.X(); + VertexIndex pos; + if (p1.Y()==_current_slice) + { + if ((pos=_x_cs[index])==-1) + { + _x_cs[index] = (VertexIndex) _mesh->vert.size(); + pos = _x_cs[index]; + Allocator::AddVertices( *_mesh, 1 ); + v = &_mesh->vert[pos]; + _volume->GetXIntercept(p1, p2, v, _thr); + return; + } + } + if (p1.Y()==_current_slice+1) + { + if ((pos=_x_ns[index])==-1) + { + _x_ns[index] = (VertexIndex) _mesh->vert.size(); + pos = _x_ns[index]; + Allocator::AddVertices( *_mesh, 1 ); + v = &_mesh->vert[pos]; + _volume->GetXIntercept(p1, p2, v,_thr); + return; + } + } + assert(pos >=0 && pos< _mesh->vert.size()); + v = &_mesh->vert[pos]; + } + void GetYIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointer &v) + { + int i = p1.X() - _bbox.min.X(); + int z = p1.Z() - _bbox.min.Z(); + VertexIndex index = i+z*_bbox.max.X(); + VertexIndex pos; + if ((pos=_y_cs[index])==-1) + { + _y_cs[index] = (VertexIndex) _mesh->vert.size(); + pos = _y_cs[index]; + Allocator::AddVertices( *_mesh, 1); + v = &_mesh->vert[ pos ]; + _volume->GetYIntercept(p1, p2, v,_thr); + } + v = &_mesh->vert[pos]; + } + void GetZIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointer &v) + { + int i = p1.X() - _bbox.min.X(); + int z = p1.Z() - _bbox.min.Z(); + VertexIndex index = i+z*_bbox.max.X(); + VertexIndex pos; + if (p1.Y()==_current_slice) + { + if ((pos=_z_cs[index])==-1) + { + _z_cs[index] = (VertexIndex) _mesh->vert.size(); + pos = _z_cs[index]; + Allocator::AddVertices( *_mesh, 1 ); + v = &_mesh->vert[pos]; + _volume->GetZIntercept(p1, p2, v,_thr); + return; + } + } + if (p1.Y()==_current_slice+1) + { + if ((pos=_z_ns[index])==-1) + { + _z_ns[index] = (VertexIndex) _mesh->vert.size(); + pos = _z_ns[index]; + Allocator::AddVertices( *_mesh, 1 ); + v = &_mesh->vert[pos]; + _volume->GetZIntercept(p1, p2, v,_thr); + return; + } + } + v = &_mesh->vert[pos]; + } + +protected: + Box3i _bbox; + + int _slice_dimension; + int _current_slice; + + VertexIndex *_x_cs; // indici dell'intersezioni della superficie lungo gli Xedge della fetta corrente + VertexIndex *_y_cs; // indici dell'intersezioni della superficie lungo gli Yedge della fetta corrente + VertexIndex *_z_cs; // indici dell'intersezioni della superficie lungo gli Zedge della fetta corrente + VertexIndex *_x_ns; // indici dell'intersezioni della superficie lungo gli Xedge della prossima fetta + VertexIndex *_z_ns; // indici dell'intersezioni della superficie lungo gli Zedge della prossima fetta + + MeshType *_mesh; + VolumeType *_volume; + + float _thr; + void NextSlice() + { + memset(_x_cs, -1, _slice_dimension*sizeof(VertexIndex)); + memset(_y_cs, -1, _slice_dimension*sizeof(VertexIndex)); + memset(_z_cs, -1, _slice_dimension*sizeof(VertexIndex)); + + std::swap(_x_cs, _x_ns); + std::swap(_z_cs, _z_ns); + + _current_slice += 1; + } + + void Begin() + { + _current_slice = _bbox.min.Y(); + + memset(_x_cs, -1, _slice_dimension*sizeof(VertexIndex)); + memset(_y_cs, -1, _slice_dimension*sizeof(VertexIndex)); + memset(_z_cs, -1, _slice_dimension*sizeof(VertexIndex)); + memset(_x_ns, -1, _slice_dimension*sizeof(VertexIndex)); + memset(_z_ns, -1, _slice_dimension*sizeof(VertexIndex)); + + } +}; +} // end namespace +} // end namespace +#endif // __VCGTEST_WALKER \ No newline at end of file diff --git a/apps/sample/trimesh_refine/trimesh_refine.cpp b/apps/sample/trimesh_refine/trimesh_refine.cpp new file mode 100644 index 00000000..df866a3a --- /dev/null +++ b/apps/sample/trimesh_refine/trimesh_refine.cpp @@ -0,0 +1,90 @@ + +// mesh definition +#include +#include +#include + +#include +#include +#include +#include + +// input output +#include +#include + +// std +#include + +using namespace vcg; +using namespace std; + +struct MyFace; +struct MyEdge; +struct MyVertex: public VertexVN{}; +struct MyFace: public FaceAF{}; +struct MyMesh: public tri::TriMesh< vector, vector >{}; + +#define FLAT 0 +#define BUTTERFLY 2 + +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 ref_step [opt] \n" + "Commands: \n" + " Refinement rules:\n" + " -m use simple midpoint subdivision (default) \n" + " -b use butterfly subdivision scheme \n" + " -l# refine only if the the edge is longer than #(default 0.0)\n" + ); + exit(0); + } + + 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(0); + } + vcg::tri::UpdateTopology::FaceFace(m); + vcg::tri::UpdateFlags::FaceBorderFromFF(m); + vcg::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(),length); 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; + vcg::tri::io::ExporterPLY::Save(m,argv[2],pi.mask); + return 0; + } diff --git a/apps/sample/trimesh_refine/trimesh_refine.pro b/apps/sample/trimesh_refine/trimesh_refine.pro new file mode 100644 index 00000000..fb7ee1d5 --- /dev/null +++ b/apps/sample/trimesh_refine/trimesh_refine.pro @@ -0,0 +1,13 @@ +###################################################################### +# 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 +LIBPATH += +DEPENDPATH += . +INCLUDEPATH += . ../../.. +CONFIG += console stl +TEMPLATE = app +SOURCES += trimesh_refine.cpp ../../../wrap/ply/plylib.cpp \ No newline at end of file diff --git a/apps/sample/trimesh_smooth/trimesh_smooth.cpp b/apps/sample/trimesh_smooth/trimesh_smooth.cpp new file mode 100644 index 00000000..7077ee37 --- /dev/null +++ b/apps/sample/trimesh_smooth/trimesh_smooth.cpp @@ -0,0 +1,51 @@ +#include + +#include +#include +#include +// to clean up a mesh +#include +#include + +// input output +#include +#include + + +using namespace vcg; + +class MyFace; +class MyEdge; +class MyVertex:public Vertex{}; +class MyFace :public FaceFN{}; +class MyMesh: public tri::TriMesh< std::vector, std::vector >{}; + + +int main(int argc,char ** argv) +{ +if(argc<3) +{ + printf("Usage: trimesh_smooth \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); + + printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,argv[1]); + + LaplacianSmooth(m,atoi(argv[2])); + tri::io::ExporterPLY::Save(m,"out.ply"); + + return 0; +} + diff --git a/apps/sample/trimesh_smooth/trimesh_smooth.pro b/apps/sample/trimesh_smooth/trimesh_smooth.pro new file mode 100644 index 00000000..1331efeb --- /dev/null +++ b/apps/sample/trimesh_smooth/trimesh_smooth.pro @@ -0,0 +1,11 @@ +###################################################################### +# Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 +###################################################################### + +TARGET = trimesh_smooth +LIBPATH += +DEPENDPATH += . +INCLUDEPATH += . ../../.. +CONFIG += console stl +TEMPLATE = app +SOURCES += trimesh_smooth.cpp ../../../wrap/ply/plylib.cpp \ No newline at end of file diff --git a/apps/sample/trimesh_topology/trimesh_topology.cpp b/apps/sample/trimesh_topology/trimesh_topology.cpp new file mode 100644 index 00000000..60c2a766 --- /dev/null +++ b/apps/sample/trimesh_topology/trimesh_topology.cpp @@ -0,0 +1,82 @@ +#include + +#include +#include +#include +#include + +// topology computation +#include + +// half edge iterators +#include + + + +using namespace vcg; + +class MyFace; +class MyEdge; +class MyVertex:public Vertex{}; +class MyFace : public FaceAFFM{}; +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(m.face[0].IsBorder(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(m.face[0].IsBorder(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; + m.UnMarkAll(); + 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 ((*fi).IsBorder(j) && !m.IsMarked(&*fi)) + { + m.Mark(&*fi); + hei.Set(&*fi,j,fi->V(j)); + he=hei; + do + { + BorderEdgeNum++; + he.NextB(); // next edge along a border + m.Mark(he.f); + } + while (he.f!=hei.f); + HoleNum++; + } + } + } + + printf("Mesh has %i holes and %i border edges\n",HoleNum,BorderEdgeNum); + return 0; +} + diff --git a/apps/sample/trimesh_topology/trimesh_topology.pro b/apps/sample/trimesh_topology/trimesh_topology.pro new file mode 100644 index 00000000..eed16d34 --- /dev/null +++ b/apps/sample/trimesh_topology/trimesh_topology.pro @@ -0,0 +1,11 @@ +###################################################################### +# Automatically generated by qmake (2.00a) ven 24. giu 14:14:20 2005 +###################################################################### + +TARGET = trimesh_topology +LIBPATH += +DEPENDPATH += . +INCLUDEPATH += . ../../.. +CONFIG += console stl +TEMPLATE = app +SOURCES += trimesh_topology.cpp \ No newline at end of file