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