trimesh2是一個開源的網格三維模型庫,支持PLY,OFF和OBJ 等三維模型文件的讀寫,查看、拼接等操作,為學習和研究提供了有用的工具。更多關於trimesh2的信息見官網:
trimesh2在windows下編譯時常出現各種錯誤,並且官方尚未提供使用vs2010編譯的源碼,給trimesh2的使用者帶來了麻煩。本文使用vs2010配置目前最新版本trimesh2-2.10。
獲取源碼:
最新版的trimesh2:trimesh2-2.10.zip。
說明:trimesh2-2.10.zip中包含了freeglut,glui和本身的trimesh三個庫。trimesh2-2.10使用的glui版本為2.01f,並添加了glui_add_controls.cc等內容,在trimesh2-2.10提供的demo中只需編譯freeglut庫,其自帶的glui庫在編譯rtsc時才需編譯。本文配置僅使用trimesh2-2.10.zip文件即可。
編譯trimesh2靜態鏈接庫項目:
一、創建項目
1、打開Microsoft Visual Studio 2010,選擇File->New->Project。
2、在New Project中選擇Installed Templates->Visual C++->Win32。
3、選擇Win32 Console Application,設置名稱:trimesh,設置解決方案名:trimesh2。
4、單擊OK,在出現的Win32 Application Wizard的Overview對話框中點擊Next。
5、在Application Settings中,選擇Application type下的Static library。
6、勾選Additional options下的Empty project。
7、單擊Finish創建項目。
二、添加源碼
1、解壓trimesh2-2.10.zip,將~\trimesh2\include文件夾拷貝到剛才新建的項目路徑路徑~\trimesh2\之下。
2、將~\trimesh2\libsrc\目錄下的所有文件拷貝到項目路徑~\trimesh2\trimesh\之下。
3、右鍵單擊項目,將~\trimesh2\trimesh\目錄下剛才拷貝的所有.cc文件添加到項目中。
4、右鍵單擊項目,選擇屬性,在VC++ Directories下的Include Directories中添加$(SolutionDir)include。
5、在項目路徑~\trimesh2\下新建文件夾bin和lib。bin存放可執行文件,lib存放庫文件。
6、右鍵單擊項目,選擇屬性,將Configuration Properties->General下的Output Directory值改為$(SolutionDir)lib。
7、單擊應用,確定,添加完畢。
三、編譯trimesh2庫
右鍵單擊項目,Build,生成鏈接庫,若沒有錯誤並且~\trimesh2\lib目錄下出現trimesh.lib文件,則編譯成功。
編譯freeglut動態鏈接庫項目:
一、創建項目
1、在New Project中選擇Installed Templates->Visual C++->Win32。
2、選擇Win32 Console Application,設置名稱:freeglut,Add to solution。
3、單擊OK,在出現的Win32 Application Wizard的Overview對話框中點擊Next。
4、在Application Settings中,選擇Application type下的Console application。
5、取消Additional options下的Precompiled header,勾選Empty project。
6、單擊Finish創建項目。
二、添加源碼
1、將~\trimesh2\gluit\目錄下的所有以freeglut_開頭的文件拷貝到項目路徑~\trimesh2\freeglut\之下。注意源碼gluit中包含了freeglut庫文件和glui庫文件,此處僅編譯freeglut。
2、單擊freeglut項目,將~\trimesh2\freeglut\目錄下剛才拷貝的所有.h和.cc文件添加到項目中。
3、單擊freeglut項目,選擇Add->Existing Item,將~\trimesh2\include\GL目錄下的freeglut.h,freeglut_ext.h,freeglut_std.h,glut.h添加到項目中來。
4、 右鍵單擊freeglut項目,選擇屬性,在VC++ Directories下的Include Directories中添加$(SolutionDir)include。
5、右鍵單擊freeglut項目,選擇屬性,將Configuration Properties->General下的Output Directory值改為$(SolutionDir)lib。
6、單擊應用,確定,添加完畢。
三、編譯freeglut庫
此時若編譯項目,則會出現鏈接錯誤: cannot open file 'freeglut_static.lib'。
解決方法為:將freeglut_std.h 文件頭中的宏定義#define FREEGLUT_STATIC注釋掉。
重新編譯通過,~\trimesh2\lib目錄下出現freeglut.lib和freeglut.dll。
創建mesh_view項目進行測試:
一、創建項目
1、選擇File->New->Project。
2、在New Project中選擇Installed Templates->Visual C++->Win32。
3、選擇Win32 Console Application,設置名稱:mesh_view。選擇Add to solution。
4、單擊OK,在出現的Win32 Application Wizard的Overview對話框中點擊Next。
5、在Application Settings中,選擇Application type下的Console application。
6、取消Additional options下的Precompiled header,勾選Empty project。
7、單擊Finish創建項目。
二、添加源碼
1、將\trimesh2-2.10\trimesh2\utilsrc\下的mesh_view.cc拷貝到~\trimesh2\mesh_view項目目錄下。
2、右鍵單擊mesh_view項目並將mesh_view.cc添加到項目。
3、右鍵單擊mesh_view項目,選擇屬性,在VC++ Directories下的Include Directories中添加$(SolutionDir)include。
4、將Configuration Properties->General下的Output Directory值改為$(SolutionDir)bin。
5、在Linker->Input的Additional Dependencies下添加:$(SolutionDir)lib\freeglut.lib
和$(SolutionDir)lib\trimesh.lib。
單擊應用,確定,添加完畢。
三、編譯運行
編譯項目,在bin目錄下生成mesh_view.exe。
將~\trimesh2\lib\下的freeglut.dll拷貝到~\trimesh2\bin\中,將mesh_view項目設置為Set up StartUp Project。Alt+F5運行。
trimesh2提供的其它工具編譯
1、trimesh2提供的mesh_cat,mesh_check,mesh_crunch,mesh_info,mesh_make和mesh_shape都可按編譯mesh_view的方法進行編譯。
2、mesh_align,mesh_cc和mesh_hf,由於使用了<unistd.h>中的庫函數getopt函數而編譯不通過,則可重寫類似功能的window版本方法如下。
頭文件:
/* POSIX getopt for Windows AT&T Public License Code given out at the 1985 UNIFORUM conference in Dallas. */ #ifdef __GNUC__ #include <getopt.h> #endif #ifndef __GNUC__ #ifndef _WINGETOPT_H_ #define _WINGETOPT_H_ #ifdef __cplusplus extern "C" { #endif extern int opterr; extern int optind; extern int optopt; extern char *optarg; extern int getopt(int argc, char **argv, char *opts); #ifdef __cplusplus } #endif #endif /* _GETOPT_H_ */ #endif /* __GNUC__ */
源文件:
/* POSIX getopt for Windows AT&T Public License Code given out at the 1985 UNIFORUM conference in Dallas. */ #ifndef __GNUC__ #include "wingetopt.h" #include <stdio.h> #define NULL 0 #define EOF (-1) #define ERR(s, c) if(opterr){\ char errbuf[2];\ errbuf[0] = c; errbuf[1] = '\n';\ fputs(argv[0], stderr);\ fputs(s, stderr);\ fputc(c, stderr);} //(void) write(2, argv[0], (unsigned)strlen(argv[0]));\ //(void) write(2, s, (unsigned)strlen(s));\ //(void) write(2, errbuf, 2);} int opterr = 1; int optind = 1; int optopt; char *optarg; int getopt(argc, argv, opts) int argc; char **argv, *opts; { static int sp = 1; register int c; register char *cp; if(sp == 1) if(optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0') return(EOF); else if(strcmp(argv[optind], "--") == NULL) { optind++; return(EOF); } optopt = c = argv[optind][sp]; if(c == ':' || (cp=strchr(opts, c)) == NULL) { ERR(": illegal option -- ", c); if(argv[optind][++sp] == '\0') { optind++; sp = 1; } return('?'); } if(*++cp == ':') { if(argv[optind][sp+1] != '\0') optarg = &argv[optind++][sp+1]; else if(++optind >= argc) { ERR(": option requires an argument -- ", c); sp = 1; return('?'); } else optarg = argv[optind++]; sp = 1; } else { if(argv[optind][++sp] == '\0') { sp = 1; optind++; } optarg = NULL; } return(c); } #endif /* __GNUC__ */
並在其文件頭添加如下宏:
#ifdef _WIN32 #include "WinGetopt.h" #else #include <unistd.h> #endif
另外mesh_cc.cc 文件中find_comps 和 TriMesh_algo.h中方法重名,請為其重新命名。
mesh_hf.cc文件中有用使用了back_inserter方法,需添加頭文件:#include <iterator> //zdd++
3、mesh_shape工具中缺少如下宏:
//zdd++ #ifndef M_PI_2 #define M_PI_2 1.57079632679489661923 /* pi/2 */ #endif #ifndef M_2_PI #define M_2_PI 6.283185307179586232 /* 2*pi */ #endif //zdd++
編譯rtsc項目:
編譯靜態鏈接庫glui。按照編譯freeglut的方法,使用~\trimesh2\gluit\目錄下的所有以glui_開頭的所有.h和.cc文件和~\include\GL下的glui.h文件,選擇Static library。創建並編譯glui。在bin中生成glui.lib庫文件。
下載rtsc-1.5.zip ,並使用其提供的(~.h\~.cc)創建rtsc項目。將$(SolutionDir)lib\freeglut.lib,$(SolutionDir)lib\trimesh.lib和$(SolutionDir)lib\glui.lib加到Linker->Input的Additional Dependencies中。其它按上述方法處理。
1、在apparentridge.h文件開頭添加:
//zdd++ #include <vector> using namespace std;
將apparentridge.cc文件中的
extern bool draw_faded; //改成 extern int draw_faded; //zdd++
在rtsc.cc開頭添加宏:
//zdd++ #ifndef M_PI_2 # define M_PI_2 1.57079632679489661923 /* pi/2 */ #endif #ifndef M_2_PI # define M_2_PI 6.283185307179586232 /* 2*pi */ #endif #ifndef M_SQRT1_2 # define M_SQRT1_2 0.707106781186547524401 /* 1/sqrt(2)*/ #endif //zdd++
編譯運行即可。
現在,跟我一起開始研究tremesh2和rtsc吧。