由於CGAL是用C++實現的,因此須要先了解一下C++編程。C++是面向對象的編程,這也是C++對C語言改進的最重要的部分。C++也被叫作是"帶類的 C"。簡單講一下類的構成,成員函數以及對象的定義和使用。html
首先從C的結構體提及。C中的結構體我想你們已經熟悉了,不熟悉的朋友能夠先了解一下,這將對你認識「類」有很好的幫助。C中的結構體存在缺點:1.main 函數中的任意賦值語句均可以訪問結構體中的成員,但在實際應用中咱們想保護本身的私密數據不被訪問,所以C語言中的結構體的數據是不安全的;2.結構體中的數據和對該數據的操做是分離的,並非一個被封裝起來的總體,所以使程序難以重用,影響了軟件生產效率。因而C++中引入了類的概念。linux
C++中類的通常格式爲:c++
class Kid { private: int age; //私有成員 char *name; char *sex; public: //公有成員 void setKid(int age,char *name,char *sex); void showKid(); };
C++中規定若是沒有對類的成員加私有private,保護protected,公有public,則默認爲私有的。而對於 C++的結構體來講,成員能夠是私有的,保護的或公有的,但默認爲公有的;還有要注意的是不能在類的聲明中給數據成員賦值。redis
通常狀況下,一個類的數據成員應該聲明爲私有的,成員函數聲明爲共有的。這樣,內部的數據隱藏在類中,在類的外部沒法訪問直接訪問,使數據獲得有效的保護。而公有的成員函數就成爲一種與類外部溝通的接口。算法
1) 普通的成員函數。
要注意幾點:1.類名和函數名之間應加上做用域運算符::,用於聲明這個成員函數是屬於哪個類的,若是在函數名前沒有類名,或既無類名又無做用域運算符::,那麼這個函數不屬於任何類,不是成員函數,而是普通函數;2.在類的聲明中,成員函數原型的參數表中能夠不說明參數的名字,而只說明它的類型,但在類外定義時必須既要說明參數類型又要說明參數名;
2) 內聯成員函數,它又分顯式聲明和隱式聲明。shell
類與對象的關係能夠用數據類型int和整形變量i之間的關係來類比。int類型和類類型表明一種抽象的概念,而整形變量和類的對象表明具體的東西。C++把類的變量稱爲類的對象,對象也被稱爲類的實例;類的對象能夠是: class Kid{...}kid1,kid2;
也能夠是聲明瞭類後,使用時在定義對象: Kid kid1,kid2;
(聲明一個類後,它並不接受和存儲具體的值,只做爲生成具體對象的一種樣板,只有定義了對象後,系統才爲對象分配存儲空間,以存放對象中的成員);編程
對對象中的成員的訪問能夠是:
1) 對象名.數據成員名/對象名.成員函數名(參數),好比api
kid1.setKid(10,"rookie_j","男");
2) 指針訪問對象中成員,好比:安全
class Kid{public: int age;}; Kid kid,*ptr; ptr=&kid; cout << ptr->age //cout<<(*ptr).age;
3) 能夠經過引用來訪問對象中的成員bash
class Kid{public: int age;}; Kid kid; Kid &ptr=kid; cout << ptr.age //cout<<kid.age;
由於接下來要講解的運用CGAL庫編寫凸包的程序,其程序運用以上的 C++的知識就能夠理解了,因此只講解以上的 C++ 的知識,具體想了解 C++的話,推薦(注意瞭解某種語言,不在於你看了多少書,而是去嘗試編寫)
1.《C++ Primer中文版》(第4版) 【原書名】 C++ Primer (4th Edition) 【原出版社】 Addison Wesley/Pearson 【做者】 (美)Stanley B.Lippman,Josée LaJoie,Barbara E.Moo 【譯者】 李師賢 【叢書名】 圖靈計算機科學叢書 【出版社】人民郵電出版社 2.《C++ Primer Plus》(第四版)中文版 【原書名】 C++ Primer Plus,Fourth Edition 【原出版社】 Sams 【做者】 (美)Stephen Prata 【譯者】 孫建春 韋強 【叢書名】 Primer Plus 系列 【出版社】 人民郵電出版社
看CGAL中演化繚亂的Kernel對我這個C++入門級的人來講是件痛苦的事。假若有時間,我會認真去看看模板類,類模板什麼的再去好好理解這些東西,可是我想大部分人在學習新的東西的時候是沒有興趣去看那麼的多參考書。因此摸着石頭過河時最好最有效的方法。如下說說這Kernel是個什麼東西,爲何要有那麼多的typedef。
CGAL的開發人員力圖讓這個程序包有較強的擴展性,要有擴展性,同時又要有必定的規則層次。這個層次的底層是代數結構,其上談number type,再往上就是基本幾何對象(線,面,點,射線,線段)和定義在基本幾何對象上的基本算法,在往上就是各類複雜的幾何算法(包圍盒,搜索,網格化等),以下圖所示。
<img src="htt://cgal_use.com/1.png" width="400" height="100">
所謂的Kernel就是Layer2的內容。CGAL將Layer2按照基本幾何對象的表達方式(用歐式座標表達仍是其次座標表達)進一步分紅Cartesian和Homogeneous兩種。簡單的說,咱們用Cartesian開始編程,之後的對象操做什麼的都是用x , y , z三個座標去表示點,線,面。
由於各個layer的東西在CGAL裏都是以類模板的形式定義。CGAL的一開始,會有一大堆typedef,其實就是給這些類模板起一個簡單而又好記的名字。看一例:
typedef CGAL:: Exact_predicates_exact_constructions_kernel K; typedef K::Ray_3 Ray; typedef K::Line_3 Line; typedef K::Point_3 Point; typedef K::Triangle_3 Triangle; typedef std::list<Triangle>::iterator Iterator; typedef CGAL::AABB_triangle_primitive<K,Iterator> Primitive;
CGAL給出了一些預約義的東西,也就是把上面那個不斷typedef的最初一部分給隱藏掉:
Exact_predicates_exact_constructions_kernel; Exact_predicates_exact_constructions_kernel_with_sqrt; Exact_predicates_inexact_constructions_kernel;
這些預約義的東西默認使用Cartesian,數據類型支持double,還包括能實現精確的幾何判斷(exact predicate ),原來的代碼能夠寫成:
typedef CGAL:: Cartesian<double> K;// 使用Cartesian座標描述幾何體,座標的數值時double型,之後用到 ray , line等幾何體的時候都按照Cartesian方式給出double型座標。 typedef K::Ray_3 Ray; typedef K::Line_3 Line; typedef K::Point_3 Point; typedef K::Triangle_3 Triangle; typedef std::list<Triangle>::iterator Iterator; typedef CGAL::AABB_triangle_primitive<K,Iterator> Primitive;//這句話表示使用高級計算幾何算法AABB時,全部的幾何對象都是Cartesian表示的,座標的數值都是double。
點擊http://doc.cgal.org/latest/Manual/packages.html| 66c998fe1f511ede5c7483b24fcc88ca4 |進入CGAL手冊,出現各類算法庫Arithmetic and Algebra、Combinatorial Algorithms、Geometry Kernels、Polygons、Arrangements等等。
假如咱們想找有關3d凸包的算法,則找到以下圖所示的算法,
點擊reference manual
,就會看到該算法庫中的Concepts、Traits Classes、Convex Hull Functions、Convexity Checking Function,以下圖:
點擊convex_hull_3
函數,就會看見該函數的使用規則和實例,以下圖
每一個算法庫中都會帶有示例程序,點擊左側列表中example->convex_hull_3/quickhull_3.cpp
,就會看到以下示例程序:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/point_generators_3.h> #include <CGAL/algorithm.h> #include <CGAL/Polyhedron_3.h> #include <CGAL/convex_hull_3.h> #include <vector> typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Polyhedron_3<K> Polyhedron_3; typedef K::Segment_3 Segment_3; // define point creator typedef K::Point_3 Point_3; typedef CGAL::Creator_uniform_3<double, Point_3> PointCreator; //a functor computing the plane containing a triangular facet struct Plane_from_facet { Polyhedron_3::Plane_3 operator()(Polyhedron_3::Facet& f) { Polyhedron_3::Halfedge_handle h = f.halfedge(); return Polyhedron_3::Plane_3( h->vertex()->point(), h->next()->vertex()->point(), h->opposite()->vertex()->point()); } }; int main() { CGAL::Random_points_in_sphere_3<Point_3, PointCreator> gen(100.0); // generate 250 points randomly on a sphere of radius 100.0 // and copy them to a vector std::vector<Point_3> points; CGAL::cpp11::copy_n( gen, 250, std::back_inserter(points) ); // define polyhedron to hold convex hull Polyhedron_3 poly; // compute convex hull of non-collinear points CGAL::convex_hull_3(points.begin(), points.end(), poly); std::cout << "The convex hull contains " << poly.size_of_vertices() << " vertices" << std::endl; // assign a plane equation to each polyhedron facet using functor Plane_from_facet std::transform( poly.facets_begin(), poly.facets_end(), poly.planes_begin(),Plane_from_facet()); return 0; }
對於用CGAL所編寫的程序(由於基於C++)可利用Cmake來進行編譯安裝。CMake是一個跨平臺的安裝(編譯)工具,能夠用簡單的語句來描述全部平臺的安裝(編譯過程)。他可以輸出各類各樣的makefile或者project文件,能測試編譯器所支持的C++特性,相似UNIX下的automake。只是 CMake 的組態檔取名爲 CmakeLists.txt。Cmake 並不直接建構出最終的軟件,而是產生標準的建構檔(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),而後再依通常的建構方式使用。這使得熟悉某個集成開發環境(IDE)的開發者能夠用標準的方式建構他的軟件,這種可使用各平臺的原生建構系統的能力是 CMake 和 SCons 等其餘相似系統的區別之處。
建議去了解一下CMake方面的知識。
linux-gentoo下cmake的安裝
$ sudo emerge -avt cmake
1) 建立一個工程目錄quickhull3
,並將上面的示例程序quickhull_3.cpp放入該目錄中
$ mkdir quickhull3 $ ls quickhull_3.cpp
2) 編寫CMakeLists.txt
文件,鑑於許多朋友不會編寫CMakeLists.txt
文件,所以這裏給出一個可自動生成CMakeLists.txt
文件的shell腳本文件create_cmakelists.sh
,該腳本僅運用於基於CGAL算法庫編寫的項目,將此腳本放在工程主目錄中,其內容以下:
#!/bin/bash # Copyright (c) 1999,2000,2002-2007,2009,2011,2012 # Utrecht University (The Netherlands), # ETH Zurich (Switzerland), # INRIA Sophia-Antipolis (France), # Max-Planck-Institute for Informatics Saarbruecken (Germany), # and Tel-Aviv University (Israel). All rights reserved. # # This file is part of CGAL (www.cgal.org); you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation; either version 3 of the License, # or (at your option) any later version. # # Licensees holding a valid commercial license may use this file in # accordance with the commercial license agreement provided with the software. # # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE # WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # # $URL: svn+ssh://fcacciola@scm.gforge.inria.fr/svn/cgal/trunk/Scripts/scripts/cgal_create_makefile $ # $Id: cgal_create_makefile 36976 2007-03-09 22:53:24Z reichel $ # # Author(s) : various # This script creates a CGAL cmake script with entries for .C and .cpp # files in the current directory - some options can be given or specified in a file #LEDA #GMP #GMPXX #MPFR #MPFI #RS #TAUCS #BLAS #LAPACK #OPENNL #QGLViewer (or implied by Qt4?) #ESBTL #NTL #Core (implies GMP+GMPXX) #Qt3 (implies QT3) #Qt4 (implies QT4) #ImageIO #not (yet) supported #F2C (comes with BLAS/LAPACK - something like that) #IPE (ask Laurent) #MKL (ask Andreas) create_cmake_script_with_options() { qt3='n' qt4='n' # parse options file if [ -e "$OPTIONS_FILE" ]; then OLDIFS="$IFS" IFS=$'\n' for LINE in `cat $OPTIONS_FILE`; do # CGAL components if [ -z "$CGAL_COMPONENTS_GIVEN" ]; then # read file only if not given! next_cgal_component=`echo $LINE | grep -v "#" | grep CGAL_COMPONENT` if [ ! -z "$next_cgal_component" ]; then next_cgal_component=${next_cgal_component/CGAL_COMPONENT /} if [ -z "$CGAL_COMPONENTS" ]; then CGAL_COMPONENTS=$next_cgal_component else CGAL_COMPONENTS=$CGAL_COMPONENTS":"$next_cgal_component fi fi fi # Boost components if [ -z "$BOOST_COMPONENTS_GIVEN" ]; then # read file only if not given! next_boost_component=`echo $LINE | grep -v "#" | grep BOOST_COMPONENT` if [ ! -z "$next_boost_component" ]; then next_boost_component=${next_boost_component/BOOST_COMPONENT /} if [ -z "$BOOST_COMPONENTS" ]; then BOOST_COMPONENTS=$next_boost_component else BOOST_COMPONENTS=$BOOST_COMPONENTS":"$next_boost_component fi fi fi done IFS="$OLDIFS" fi # print makefile header #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # Created by the script cgal_create_cmake_script_with_options # This is the CMake script for compiling a set of CGAL applications. EOF #--------------------------------------------------------------------------- if [ "$SINGLE_SOURCE" = "n" ]; then echo "project( ${PROJECT} )" else echo "project( ${SOURCE} )" fi #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' cmake_minimum_required(VERSION 2.6.2) if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6) if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3) cmake_policy(VERSION 2.8.4) else() cmake_policy(VERSION 2.6) endif() endif() set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true ) if ( COMMAND cmake_policy ) cmake_policy( SET CMP0003 NEW ) endif() # CGAL and its components EOF if [ -n "$ENABLE_CTEST" ]; then echo "enable_testing()" fi #--------------------------------------------------------------------------- # echo "CGAL_COMPONENTS: $CGAL_COMPONENTS" # echo "CGAL_PRECONFIGURED_LIBS: $CGAL_PRECONFIGURED_LIBS" if [ ! -z "$CGAL_COMPONENTS" ]; then # ensure capitalization # CGAL: Core, Qt3, Qt4, PDB, ImageIO CGAL_COMPONENTS=${CGAL_COMPONENTS//[c|C][o|O][r|R][e|E]/Core} CGAL_COMPONENTS=${CGAL_COMPONENTS//[q|Q][t|T]3/Qt3} CGAL_COMPONENTS=${CGAL_COMPONENTS//[q|Q][t|T]4/Qt4} CGAL_COMPONENTS=${CGAL_COMPONENTS//[i|I][m|M][a|A][g|G][e|E][i|I][o|O]/ImageIO} # external libs CGAL_COMPONENTS=${CGAL_COMPONENTS//[g|G][m|M][p|P]/GMP} CGAL_COMPONENTS=${CGAL_COMPONENTS//[g|G][m|M][p|P][x|X][x|X]/GMPXX} CGAL_COMPONENTS=${CGAL_COMPONENTS//[m|M][p|P][f|F][r|R]/MPFR} CGAL_COMPONENTS=${CGAL_COMPONENTS//[l|L][e|E][d|D][a|A]/LEDA} CGAL_COMPONENTS=${CGAL_COMPONENTS//[m|M][p|P][f|F][i|I]/MPFI} CGAL_COMPONENTS=${CGAL_COMPONENTS//[r|R][s|S]/RS} CGAL_COMPONENTS=${CGAL_COMPONENTS//[o|O][p|P][e|E][n|N][n|N][l|L]/OpenNL} CGAL_COMPONENTS=${CGAL_COMPONENTS//[t|T][a|A][u|U][c|C][s|S]/TAUCS} CGAL_COMPONENTS=${CGAL_COMPONENTS//[b|B][l|L][a|A][s|S]/BLAS} CGAL_COMPONENTS=${CGAL_COMPONENTS//[l|L][a|A][p|P][a|A][c|C][k|K]/LAPACK} CGAL_COMPONENTS=${CGAL_COMPONENTS//[q|Q][g|G][l|L][v|V][i|I][e|E][w|W][e|E][r|R]/QGLViewer} CGAL_COMPONENTS=${CGAL_COMPONENTS//[z|Z][l|L][i|I][b|B]/zlib} CGAL_COMPONENTS=${CGAL_COMPONENTS//[e|E][s|S][b|B][t|T][l|L]/ESBTL} CGAL_COMPONENTS=${CGAL_COMPONENTS//[n|N][t|T][l|L]/NTL} CGAL_COMPONENTS=${CGAL_COMPONENTS//[o|O][p|P][e|E][n|N][g|G][l|L]/OpenGL} #F2C? #IPE? #MKL? OLDIFS="$IFS" IFS=':' for cgal_component in $CGAL_COMPONENTS; do COMPONENT=`echo $cgal_component | tr '[:upper:]' '[:lower:]'` # for qtmoc if [ "$COMPONENT" = "qt3" ]; then qt3='y' fi if [ "$COMPONENT" = "qt4" ]; then qt4='y' fi done IFS=$OLDIFS fi if [ "$CGAL_PRECONFIGURED_LIBS" = "y" ]; then CGAL_COMPONENTS=${CGAL_COMPONENTS}" ALL_PRECONFIGURED_LIBS" fi echo "find_package( CGAL QUIET COMPONENTS ${CGAL_COMPONENTS//:/ } )" #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' if ( NOT CGAL_FOUND ) message(STATUS "This project requires the CGAL library, and will not be compiled.") return() endif() # include helper file include( ${CGAL_USE_FILE} ) EOF #--------------------------------------------------------------------------- #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # Boost and its components EOF #--------------------------------------------------------------------------- if [ ! -z "$BOOST_COMPONENTS" ]; then echo "find_package( Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS//:/ } )" else echo "find_package( Boost REQUIRED )" fi # additional Boost components #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' if ( NOT Boost_FOUND ) message(STATUS "This project requires the Boost library, and will not be compiled.") return() endif() EOF #--------------------------------------------------------------------------- #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # include for local directory EOF #--------------------------------------------------------------------------- if [ -d include ] ; then echo 'include_directories( BEFORE include )' fi #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # include for local package EOF #--------------------------------------------------------------------------- # includes for local package if [ -d ../../include ] ; then echo 'include_directories( BEFORE ../../include )' fi if [ -d ../include ] ; then echo 'include_directories( BEFORE ../include )' fi if [ ! -z "$PACKAGES" ]; then #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # include of additional packages EOF #------------------------------------------------------------------------- fi # Qt3 or Qt4 if [ "$qt3" = "y" ]; then #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # Qt3 # FindQt3-patched.cmake is FindQt3.cmake patched by CGAL developers, so # that it can be used together with FindQt4: all its variables are prefixed # by "QT3_" instead of "QT_". find_package(Qt3-patched QUIET ) if ( NOT QT3_FOUND ) message(STATUS "This project requires the Qt3 library, and will not be compiled.") return() endif() if ( CGAL_Qt3_FOUND ) include( Qt3Macros-patched ) endif() EOF #------------------------------------------------------------------------- fi # qt3 if [ "$qt4" = "y" ]; then #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # Qt4 set( QT_USE_QTXML true ) set( QT_USE_QTMAIN true ) set( QT_USE_QTSCRIPT true ) set( QT_USE_QTOPENGL true ) find_package(Qt4) if ( NOT QT_FOUND ) message(STATUS "This project requires the Qt4 library, and will not be compiled.") return() endif() EOF #------------------------------------------------------------------------- fi #qt4 if [ ! -z "$BOOST_COMPONENTS" ]; then #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # Boost linking EOF #------------------------------------------------------------------------- OLDIFS="$IFS" IFS=':' for boost_component in $BOOST_COMPONENTS; do BOOST_COMPONENT=`echo $boost_component | tr '[:lower:]' '[:upper:]'` echo "add_definitions( \"-DCGAL_USE_BOOST_${BOOST_COMPONENT}\" )" echo "list(APPEND CGAL_3RD_PARTY_LIBRARIES \${Boost_${BOOST_COMPONENT}_LIBRARY} )" done IFS=$OLDIFS fi # additional Boost components # All Files or Single Source if [ "$SINGLE_SOURCE" = "n" ]; then #======================================= ############### # ALL SOURCES # ############### #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # Creating entries for all .cpp/.C files with "main" routine # ########################################################## EOF #------------------------------------------------------------------------- if [ "$qt4" = "y" ]; then echo "include( CGAL_CreateSingleSourceCGALProgramQt4 )" else echo "include( CGAL_CreateSingleSourceCGALProgram )" fi # add a new line echo # Qt3 if [ "$qt3" = "y" ]; then #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' if ( CGAL_Qt3_FOUND AND QT3_FOUND ) EOF #----------------------------------------------------------------------- for file in `ls *.C *.cpp 2> /dev/null | sort` ; do # Create an executable for each cpp that contains a function "main()" BASE=`basename $file .C` BASE=`basename $BASE .cpp` egrep '\bmain[ \t]*\(' $file >/dev/null 2>&1 if [ $? -eq 0 ]; then echo "qt3_automoc( ${file} )" fi done #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # Make sure the compiler can find generated .moc files include_directories( BEFORE ${CMAKE_CURRENT_BINARY_DIR} ) include_directories( ${QT3_INCLUDE_DIR} ) list(APPEND CGAL_3RD_PARTY_LIBRARIES ${QT3_LIBRARIES} ) endif() EOF #----------------------------------------------------------------------- fi # qt3 # Qt4 if [ "$qt4" = "y" ]; then #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' if ( CGAL_Qt4_FOUND AND QT_FOUND ) include( ${QT_USE_FILE} ) include_directories( ${QT_INCLUDE_DIR} ) endif() EOF #----------------------------------------------------------------------- fi # qt4 for file in `ls *.C *.cpp 2> /dev/null | sort`; do # Create an executable for each cpp that contains a function "main()" BASE=`basename $file .C` BASE=`basename $BASE .cpp` egrep '\bmain[ \t]*\(' $file >/dev/null 2>&1 if [ $? -eq 0 ]; then if [ "$qt4" = "y" ]; then echo "create_single_source_cgal_program_qt4( \"$file\" )" else echo "create_single_source_cgal_program( \"$file\" )" fi if [ -n "$ENABLE_CTEST" ]; then if [ -f "$BASE.cin" ] ; then CIN=" < $BASE.cin" else CIN= fi cat <<EOF add_test( "$BASE" \${CMAKE_CTEST_COMMAND} --build-and-test "\${CMAKE_CURRENT_SOURCE_DIR}" "\${CMAKE_CURRENT_BINARY_DIR}" --build-generator "\${CMAKE_GENERATOR}" --build-makeprogram "\${CMAKE_MAKE_PROGRAM}" --build-target $BASE --build-no-clean --build-run-dir "\${CMAKE_CURRENT_SOURCE_DIR}" --test-command sh -c "\${CMAKE_CURRENT_BINARY_DIR}/$BASE$CIN" ) EOF fi fi #add a new line echo done else #====================================================================== ################# # SINGLE_SOURCE # ################# target_name=$SOURCE echo echo echo "# Creating entries for target: $target_name" #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # ############################ EOF #------------------------------------------------------------------------- for file in `ls *.C *.cpp 2> /dev/null | sort`; do all="$all $file" done # Qt3 if [ "$qt3" = "y" ]; then #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' if ( CGAL_Qt3_FOUND AND QT3_FOUND ) EOF #----------------------------------------------------------------------- echo "qt3_automoc( ${all} )" #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' # Make sure the compiler can find generated .moc files include_directories( BEFORE ${CMAKE_CURRENT_BINARY_DIR} ) include_directories( ${QT3_INCLUDE_DIR} ) endif() EOF #----------------------------------------------------------------------- fi # qt3 # Qt4 if [ "$qt4" = "y" ]; then #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' if ( CGAL_Qt4_FOUND AND QT_FOUND ) include( ${QT_USE_FILE} ) include_directories( ${QT_INCLUDE_DIR} ) EOF #----------------------------------------------------------------------- echo " # UI files (Qt Designer files)" for file in `ls *.ui 2> /dev/null | sort`; do echo " qt4_wrap_ui( DT_UI_FILES $file )" done echo echo " # qrc files (resources files, that contain icons, at least)" for file in `ls *.qrc 2> /dev/null | sort`; do echo " qt4_add_resources ( DT_RESOURCE_FILES ./$file )" done echo MOC_FILES="" echo " # use the Qt MOC preprocessor on classes that derives from QObject" for file in `ls include/*.h 2> /dev/null | sort`; do BASE=`basename $file .h` egrep 'Q_OBJECT' $file >/dev/null 2>&1 if [ $? -eq 0 ]; then echo " qt4_generate_moc( include/${BASE}.h ${BASE}.moc )" MOC_FILES="${BASE}.moc $MOC_FILES" fi done for file in `ls *.h 2> /dev/null | sort`; do BASE=`basename $file .h` egrep 'Q_OBJECT' $file >/dev/null 2>&1 if [ $? -eq 0 ]; then echo " qt4_generate_moc( ${BASE}.h ${BASE}.moc )" MOC_FILES="${BASE}.moc $MOC_FILES" fi done for file in `ls *.cpp 2> /dev/null | sort`; do BASE=`basename $file .cpp` egrep 'Q_OBJECT' $file >/dev/null 2>&1 if [ $? -eq 0 ]; then echo " qt4_generate_moc( ${BASE}.cpp ${BASE}.moc )" MOC_FILES="${BASE}.moc $MOC_FILES" fi done #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' endif() EOF #----------------------------------------------------------------------- all="${all} ${MOC_FILES} \${DT_UI_FILES} \${DT_RESOURCE_FILES}" fi # qt4 # no 'cat' here, as variable substitution required echo echo "add_executable( ${target_name} ${all} )" echo echo "add_to_cached_list( CGAL_EXECUTABLE_TARGETS ${target_name} )" echo echo "# Link the executable to CGAL and third-party libraries" LIBS="" if [ "$qt3" = "y" ]; then LIBS="\${QT3_LIBRARIES}" fi if [ "$qt4" = "y" ]; then LIBS="\${QT_LIBRARIES}" fi LIBS=$LIBS" \${CGAL_LIBRARIES} \${CGAL_3RD_PARTY_LIBRARIES}" echo "target_link_libraries(${target_name} $LIBS )" fi # single source or all files #=========================================== #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cat << 'EOF' EOF #--------------------------------------------------------------------------- echo } usage() { echo "Usage: `basename $0` [-s source] [-c cgal-component1:cgal-component2:...] [-b boost-component1:boost-component2:...] [-p] [-o options_file='`pwd`/cgal_cmake_options:$HOME/.cgal_cmake_options_rc'] [-v] [-h]" >&2 echo >&2 echo " -s source If this parameter is given the script will create one single executable for 'source' with all source files; otherwise it creates one executable for each main'ed source." >&2 echo " cgal_componentX - must be a valid cgal component, examples are 'Core','ImageIO','Qt3','Qt4' ('benchmark', 'symbolic')." >&2 echo " boost_componentX - must be a valid boost component, like 'filesystem', 'program_options'." >&2 echo " -p use all of CGAL's preconfigured libraries" >&2 echo " -o options_file - file with PACKAGE, DIRECTORY, CGAL_COMPONENT, and BOOST_COMPONENT directives" >&2 echo " -v the version" >&2 echo " -h this info screen" >&2 echo >&2 } SINGLE_SOURCE='n' SOURCE="" CGAL_COMPONENTS_GIVEN="" CGAL_COMPONENTS="" CGAL_PRECONFIGURED_LIBS='n' BOOST_COMPONENTS_GIVEN="" BOOST_COMPONENTS="" OPTIONS_FILE=`pwd`"/cgal_cmake_options" if [ ! -e "$OPTIONS_FILE" ]; then OPTIONS_FILE="${HOME}/.cgal_cmake_options_rc" fi # parse command line arguments while getopts s:c:b:o:phvt OPT; do case "$OPT" in s) SINGLE_SOURCE='y' SOURCE=$OPTARG if [ "${SOURCE:(-4)}" = ".cpp" ]; then echo "Error: Source must not end with '.cpp'!" >&2 echo usage exit 2 fi if [ "${SOURCE:(-2)}" = ".C" ]; then echo "Error: Source must not end with '.C'!" >&2 echo usage exit 2 fi ;; c) CGAL_COMPONENTS_GIVEN='y' CGAL_COMPONENTS=$OPTARG ;; b) BOOST_COMPONENTS_GIVEN='y' BOOST_COMPONENTS=$OPTARG ;; o) OPTIONS_FILE=$OPTARG if [ ! -e "$OPTIONS_FILE" ]; then echo "Options-file '$OPTIONS_FILE' does not exist." >&2 exit 1 fi ;; p) CGAL_PRECONFIGURED_LIBS='y' ;; t) ENABLE_CTEST='y' ;; h) usage exit 0 ;; v) echo "`basename $0` version 0.1" exit 0 ;; \?) # getopts issues an error message usage exit 1 ;; esac done shift `expr $OPTIND - 1` #echo "FILE: $OPTIONS_FILE" #echo "BOOST_COMPONENTS: $BOOST_COMPONENTS" echo "CGAL_COMPONENTS: $CGAL_COMPONENTS" #echo "SINGLE_SOURCE: $SINGLE_SOURCE" #echo "SOURCE: $SOURCE" OUTPUTFILE=CMakeLists.txt PROJECT=`basename $PWD` if [ -f ${OUTPUTFILE} ] ; then echo "moving $OUTPUTFILE to ${OUTPUTFILE}.bak ..." echo mv -f $OUTPUTFILE ${OUTPUTFILE}.bak fi create_cmake_script_with_options | tee $OUTPUTFILE echo echo "created $OUTPUTFILE in $PWD ..."
$ ./create_cmakelists.sh $ ls CMakeLists.txt quickhull_3.cpp
3) 爲了保持代碼目錄的整潔,建議採用外部編譯,即新建一個build
目錄,在該目錄下配置編譯,其過程以下:
$ mkdir build && cd build $ cmake .. $ make $ ./quickhull_3.cpp The convex hull contains 89 vertices