OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #include <vector> 00026 #include <map> 00027 00028 #include "WGeometryFunctions.h" 00029 00030 void tesselateIcosahedron( std::vector< WVector3d >* vertices, std::vector< unsigned int >* triangles, unsigned int level ) 00031 { 00032 WAssert( vertices, "Missing input vector." ); 00033 WAssert( triangles, "Missing input vector." ); 00034 vertices->clear(); 00035 triangles->clear(); 00036 00037 unsigned int nv = 12; 00038 unsigned int nt = 20; 00039 for( unsigned int t = 1; t <= level; ++t ) 00040 { 00041 nv += 3 * nt / 2; 00042 nt *= 4; 00043 } 00044 vertices->reserve( nv ); 00045 triangles->reserve( nt ); 00046 00047 // add icosahedron vertices 00048 double phi = 0.5 * ( 1.0 + sqrt( 5.0 ) ); 00049 00050 std::vector< WVector3d > g; 00051 00052 vertices->push_back( WVector3d( phi, 1, 0 ) ); // 0 00053 vertices->push_back( WVector3d( -phi, 1, 0 ) ); // 1 00054 vertices->push_back( WVector3d( phi, -1, 0 ) ); // 2 00055 vertices->push_back( WVector3d( -phi, -1, 0 ) ); // 3 00056 00057 vertices->push_back( WVector3d( 1, 0, phi ) ); // 4 00058 vertices->push_back( WVector3d( -1, 0, phi ) ); // 5 00059 vertices->push_back( WVector3d( 1, 0, -phi ) ); // 6 00060 vertices->push_back( WVector3d( -1, 0, -phi ) ); // 7 00061 00062 vertices->push_back( WVector3d( 0, phi, 1 ) ); // 8 00063 vertices->push_back( WVector3d( 0, -phi, 1 ) ); // 9 00064 vertices->push_back( WVector3d( 0, phi, -1 ) ); // 10 00065 vertices->push_back( WVector3d( 0, -phi, -1 ) ); // 11 00066 00067 for( std::vector< WVector3d >::iterator it = vertices->begin(); it != vertices->end(); ++it ) 00068 { 00069 *it = normalize( *it ); 00070 } 00071 00072 // add triangle indices 00073 unsigned int inc[ 60 ] = 00074 { 00075 8, 5, 4, 00076 8, 4, 0, 00077 8, 0, 10, 00078 8, 10, 1, 00079 8, 1, 5, 00080 5, 9, 4, 00081 4, 2, 0, 00082 0, 6, 10, 00083 10, 7, 1, 00084 1, 3, 5, 00085 4, 9, 2, 00086 0, 2, 6, 00087 10, 6, 7, 00088 1, 7, 3, 00089 5, 3, 9, 00090 9, 11, 2, 00091 2, 11, 6, 00092 6, 11, 7, 00093 7, 11, 3, 00094 3, 11, 9 00095 }; 00096 triangles->assign( inc, inc + 60 ); 00097 00098 std::map< utility::Edge, unsigned int > edgeVertices; 00099 00100 for( unsigned int t = 0; t < level; ++t ) 00101 { 00102 // for every triangle 00103 std::size_t numTriangles = triangles->size() / 3; 00104 for( std::size_t k = 0; k < numTriangles; ++k ) 00105 { 00106 unsigned int idx[ 3 ]; 00107 // generate a new vertex for every edge (if there is no vertex yet) 00108 00109 for( int i = 0; i < 3; ++i ) 00110 { 00111 utility::Edge e( ( *triangles )[ 3 * k + i ], ( *triangles )[ 3 * k + ( i + 1 ) % 3 ] ); 00112 if( edgeVertices.find( e ) == edgeVertices.end() ) 00113 { 00114 WVector3d v0 = vertices->at( e.first ); 00115 WVector3d v1 = vertices->at( e.second ); 00116 WVector3d v = v0 + v1; 00117 v = normalize( v ); 00118 vertices->push_back( v ); 00119 edgeVertices[ e ] = vertices->size() - 1; 00120 } 00121 idx[ i ] = edgeVertices[ e ]; 00122 } 00123 00124 // make 4 triangles from the current one 00125 // add 1st triangle 00126 triangles->push_back( ( *triangles )[ 3 * k + 0 ] ); 00127 triangles->push_back( idx[ 0 ] ); 00128 triangles->push_back( idx[ 2 ] ); 00129 00130 // add 2nd triangle 00131 triangles->push_back( ( *triangles )[ 3 * k + 1 ] ); 00132 triangles->push_back( idx[ 1 ] ); 00133 triangles->push_back( idx[ 0 ] ); 00134 00135 // add 3rd triangle 00136 triangles->push_back( ( *triangles )[ 3 * k + 2 ] ); 00137 triangles->push_back( idx[ 2 ] ); 00138 triangles->push_back( idx[ 1 ] ); 00139 00140 // changed indices of this triangle to the indices of the 4th triangle 00141 ( *triangles )[ 3 * k + 0 ] = idx[ 0 ]; 00142 ( *triangles )[ 3 * k + 1 ] = idx[ 1 ]; 00143 ( *triangles )[ 3 * k + 2 ] = idx[ 2 ]; 00144 } 00145 edgeVertices.clear(); 00146 } 00147 }