Initial Relase

This commit is contained in:
Paolo Cignoni 2005-09-21 10:29:33 +00:00
parent a9c5d8fd42
commit ab22877d1d
19 changed files with 1246 additions and 0 deletions

15
apps/sample/sample.pro Normal file
View File

@ -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

51
apps/sample/sample.sln Normal file
View File

@ -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

View File

@ -0,0 +1,42 @@
#include <stdio.h>
#include<vcg/math/base.h>
#include<vcg/space/point3.h>
#include<vcg/space/point4.h>
#include<vcg/space/color4.h>
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<float>
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<unsigned char>
// 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;
}

View File

@ -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

View File

@ -0,0 +1,26 @@
#ifndef __MYMESH
#define __MYMESH
#include <vector>
// stuff to define the mesh
#include <vcg/simplex/vertex/with/afvmvnvq.h>
#include <vcg/simplex/face/with/afavfnfq.h>
#include <vcg/complex/trimesh/base.h>
#include <vcg/space/point2.h>
// the trackball
#include <wrap/gui/trackball.h>
class MyFace;
class MyEdge;
class MyVertex:public vcg::VertexAFVMVNVQ<float,MyEdge , MyFace, MyEdge>{
public: vcg::Point3f tx,ty;
} ;
class MyFace:public vcg::FaceAFAVFNFQ<MyVertex,MyEdge , MyFace> {
public:
int * r; // belongs to region r
int ip; // which plane of r
};
class MyMesh: public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > >{};
#endif

View File

@ -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 <iostream>
#include <fstream>
#include <SDL/SDL.h>
#include <gl/glew.h>
#include <GL/glu.h>
#include <GL/glut.h>
#ifdef _SHOW_A_MESH
// the trimesh drawer
#include "mesh_type.h"
#include <wrap/gl/trimesh.h>
#endif //_SHOW_A_MESH
#include <wrap/gui/trackball.h>
bool fullscreen = false, quit = false,keepdrawing = true;
int width =1024;
int height = 768;
int x,y;
vcg::GlTrimesh<MyMesh> 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<vcg::GLW::DMSmooth,vcg::GLW::CMNone,vcg::GLW::TMNone> ();break;
case 1: glWrap.Draw<vcg::GLW::DMPoints,vcg::GLW::CMNone,vcg::GLW::TMNone> (); break;
case 2: glWrap.Draw<vcg::GLW::DMWire,vcg::GLW::CMNone,vcg::GLW::TMNone> ();break;
case 3: glWrap.Draw<vcg::GLW::DMFlatWire,vcg::GLW::CMNone,vcg::GLW::TMNone> ();break;
case 4: glWrap.Draw<vcg::GLW::DMHidden,vcg::GLW::CMNone,vcg::GLW::TMNone> ();break;
case 5: glWrap.Draw<vcg::GLW::DMFlat,vcg::GLW::CMNone,vcg::GLW::TMNone> ();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<double,int> > H;
for(int ii=0;ii<hits;ii++){
//TRACE("%ui %ui %ui %ui\n",selectBuf[ii*4],selectBuf[ii*4+1],selectBuf[ii*4+2],selectBuf[ii*4+3]);
H.push_back( std::pair<double,int>(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

View File

@ -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 <vcg/complex/trimesh/create/platonic.h>
#include <vcg/complex/trimesh/update/bounding.h>
#include <vcg/complex/trimesh/update/normal.h>
#include <wrap/io_trimesh/import_ply.h>
#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<MyMesh>::Open(mesh,argv[1]);
// update bounding box
vcg::tri::UpdateBounding<MyMesh>::Box(mesh);
// update bounding box
vcg::tri::UpdateNormals<MyMesh>::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);
}

View File

@ -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

View File

@ -0,0 +1,44 @@
#include <stdio.h>
#include<vcg/simplex/vertex/vertex.h>
#include<vcg/simplex/vertex/with/vn.h>
#include<vcg/simplex/face/with/fn.h>
#include<vcg/simplex/face/with/fcfn.h>
#include<vcg/complex/trimesh/base.h>
#include<vcg/complex/trimesh/create/platonic.h>
#include<vcg/complex/trimesh/update/normal.h>
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<AVertex>, std::vector<AFace> > {};
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<CVertex>, std::vector<CFace> > {};
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<CMesh>::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<AMesh>::PerFace(am);
return 0;
}

View File

@ -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

View File

@ -0,0 +1,146 @@
#include <stdio.h>
#include <wrap/io_trimesh/export_ply.h>
#include <vcg/space/point3.h>
#include <vcg/space/box3.h>
#include <vcg/math/perlin_noise.h>
#include "trivial_walker.h"
#include <vcg/complex/trimesh/create/marching_cubes.h>
#include <vcg/complex/trimesh/create/extended_marching_cubes.h>
using namespace std;
using namespace vcg;
#include <vcg/simplex/vertex/vertex.h>
#include <vcg/simplex/face/face.h>
#include <vcg/complex/trimesh/base.h>
#include <vcg/complex/trimesh/allocate.h>
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 VOX_TYPE>
class Volume
{
public:
typedef VOX_TYPE VoxelType;
vector<VoxelType> 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<float>::quiet_NaN( );
}
float &Val(const int &x,const int &y,const int &z) {
return V(x,y,z).V();
//else return numeric_limits<float>::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<VertexPointerType,XAxis>(p1,p2,v,thr); }
template < class VertexPointerType >
void GetYIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointerType &v, const float thr)
{ GetIntercept<VertexPointerType,YAxis>(p1,p2,v,thr); }
template < class VertexPointerType >
void GetZIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointerType &v, const float thr)
{ GetIntercept<VertexPointerType,ZAxis>(p1,p2,v,thr); }
};
template <class VolumeType>
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<SimpleVoxel> MyVolume;
int main(int argc, char *argv[])
{
MyVolume volume;
typedef vcg::tri::TrivialWalker<MyMesh,MyVolume> MyWalker;
typedef vcg::tri::MarchingCubes<MyMesh, MyWalker> 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<MyMarchingCubes>(mc_mesh, volume, mc, 20*20);
vcg::tri::io::ExporterPLY<MyMesh>::Save( mc_mesh, "marching_cubes.ply");
printf("OK!\n");
};

View File

@ -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

View File

@ -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 MeshType, class VolumeType>
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<class EXTRACTOR_TYPE>
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<MeshType>::AddVertices( *_mesh, 1 );
v = &_mesh->vert[pos];
_volume->GetXIntercept<VertexPointer>(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<MeshType>::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<MeshType>::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<MeshType>::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<MeshType>::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

View File

@ -0,0 +1,90 @@
// mesh definition
#include <vcg/simplex/vertex/with/vn.h>
#include <vcg/simplex/face/with/af.h>
#include <vcg/complex/trimesh/base.h>
#include <vcg/complex/trimesh/update/topology.h>
#include <vcg/complex/trimesh/update/normal.h>
#include <vcg/complex/trimesh/update/flag.h>
#include <vcg/complex/trimesh/refine.h>
// input output
#include <wrap/io_trimesh/import_ply.h>
#include <wrap/io_trimesh/export_ply.h>
// std
#include <vector>
using namespace vcg;
using namespace std;
struct MyFace;
struct MyEdge;
struct MyVertex: public VertexVN<float,MyEdge,MyFace>{};
struct MyFace: public FaceAF<MyVertex,MyEdge,MyFace>{};
struct MyMesh: public tri::TriMesh< vector<MyVertex>, vector<MyFace> >{};
#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<argc)
{
if(argv[i][0]!='-')
{printf("Error unable to parse option '%s'\n",argv[i]); exit(0);}
switch(argv[i][1])
{
case 'm' : RefMode=FLAT; break;
case 'b' : RefMode=BUTTERFLY; break;
case 'l' : length=(float)atof(argv[i]+2); break;
default : {printf("Error unable to parse option '%s'\n",argv[i]); exit(0);}
}
++i;
}
MyMesh m;
if(vcg::tri::io::ImporterPLY<MyMesh>::Open(m,argv[1])!=0)
{
printf("Error reading file %s\n",argv[1]);
exit(0);
}
vcg::tri::UpdateTopology<MyMesh>::FaceFace(m);
vcg::tri::UpdateFlags<MyMesh>::FaceBorderFromFF(m);
vcg::tri::UpdateNormals<MyMesh>::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<MyMesh, MidPoint<MyMesh> >(m,MidPoint<MyMesh>(),length); break;
case BUTTERFLY: Refine<MyMesh, MidPointButterfly<MyMesh> >(m,MidPointButterfly<MyMesh>(),length); break;
}
}
printf("Output mesh vn:%i fn:%i\n",m.vn,m.fn);
vcg::tri::io::PlyInfo pi;
vcg::tri::io::ExporterPLY<MyMesh>::Save(m,argv[2],pi.mask);
return 0;
}

View File

@ -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

View File

@ -0,0 +1,51 @@
#include <vector>
#include<vcg/simplex/vertex/vertex.h>
#include<vcg/simplex/face/with/fn.h>
#include<vcg/complex/trimesh/base.h>
// to clean up a mesh
#include<vcg/complex/trimesh/clean.h>
#include<vcg/complex/trimesh/smooth.h>
// input output
#include <wrap/io_trimesh/import.h>
#include <wrap/io_trimesh/export_ply.h>
using namespace vcg;
class MyFace;
class MyEdge;
class MyVertex:public Vertex<float,MyEdge,MyFace>{};
class MyFace :public FaceFN<MyVertex,MyEdge,MyFace>{};
class MyMesh: public tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > >{};
int main(int argc,char ** argv)
{
if(argc<3)
{
printf("Usage: trimesh_smooth <filename> <steps>\n");
return 0;
}
MyMesh m;
//open a mesh
int err = tri::io::Importer<MyMesh>::Open(m,argv[1]);
if(err) {
printf("Error in reading %s: '%s'\n",argv[1],tri::io::Importer<MyMesh>::ErrorMsg(err));
exit(-1);
}
// some cleaning to get rid of bad file formats like stl that duplicate vertexes..
int dup = tri::Clean<MyMesh>::RemoveDuplicateVertex(m);
int unref = tri::Clean<MyMesh>::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<MyMesh>::Save(m,"out.ply");
return 0;
}

View File

@ -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

View File

@ -0,0 +1,82 @@
#include <vector>
#include<vcg/simplex/vertex/vertex.h>
#include<vcg/simplex/face/with/affm.h>
#include<vcg/complex/trimesh/base.h>
#include<vcg/complex/trimesh/create/platonic.h>
// topology computation
#include<vcg/complex/trimesh/update/topology.h>
// half edge iterators
#include<vcg/simplex/face/pos.h>
using namespace vcg;
class MyFace;
class MyEdge;
class MyVertex:public Vertex<float,MyEdge,MyFace>{};
class MyFace : public FaceAFFM<MyVertex,MyEdge,MyFace>{};
class MyMesh : public tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > >{};
int main(int ,char ** ){
MyMesh m;
//generate a mesh
vcg::tri::Icosahedron(m);
//update the face-face topology
vcg::tri::UpdateTopology<MyMesh>::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<MyFace>(m.face[0],0); // Detach the face [0] from the mesh
vcg::face::FFDetach<MyFace>(m.face[0],1);
vcg::face::FFDetach<MyFace>(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<MyMesh::FaceType> 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;
}

View File

@ -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