Initial Relase
This commit is contained in:
parent
a9c5d8fd42
commit
ab22877d1d
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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");
|
||||||
|
};
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue