polymesh.cpp

Go to the documentation of this file.
00001 /*
00002     RenderStack  Support library for OpenGL 3+
00003     Copyright (C) 2010  Timo Suoranta
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Lesser General Public
00007     License as published by the Free Software Foundation; either
00008     version 2.1 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Lesser General Public License for more details.
00014 
00015     You should have received a copy of the GNU Lesser General Public
00016     License along with this library; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 
00027 #include "renderstack/buffer.hpp"
00028 #include "renderstack/mesh.hpp"
00029 #include "renderstack/rs_gl.h"
00030 
00031 #include "mesh3d/geometry.h"
00032 #include "mesh3d/corner.h"
00033 #include "mesh3d/vec2.h"
00034 
00035 #include "renderstack/shapes/polymesh.hpp"
00036 
00037 #include <set>
00038 
00039 namespace renderstack { namespace shapes { 
00040 
00041 static const double sq2 = std::sqrt(2.0);
00042 static const double sq3 = std::sqrt(3.0);
00043 static const double sq5 = std::sqrt(5.0);
00044 
00045 void polymesh::push_point(float x, float y, float z)
00046 {
00047     m_geometry.make_point(x, y, z);
00048 }
00049 
00050 void polymesh::push_point(double x, double y, double z)
00051 {
00052     m_geometry.make_point(x, y, z);
00053 }
00054 
00055 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0)
00056 {
00057     return m_geometry.make_polygon(p0);
00058 }
00059 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0, mesh3d::point *p1)
00060 {
00061     return m_geometry.make_polygon(p0, p1);
00062 }
00063 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0, mesh3d::point *p1, mesh3d::point *p2)
00064 {
00065     return m_geometry.make_polygon(p0, p1, p2);
00066 }
00067 
00068 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0, mesh3d::point *p1, mesh3d::point *p2, mesh3d::point *p3)
00069 {
00070     return m_geometry.make_polygon(p0, p1, p2, p3);
00071 }
00072 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0, mesh3d::point *p1, mesh3d::point *p2, mesh3d::point *p3, mesh3d::point *p4)
00073 {
00074     return m_geometry.make_polygon(p0, p1, p2, p3, p4);
00075 }
00076 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0, mesh3d::point *p1, mesh3d::point *p2, mesh3d::point *p3, mesh3d::point *p4, mesh3d::point *p5)
00077 {
00078     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5);
00079 }
00080 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0, mesh3d::point *p1, mesh3d::point *p2, mesh3d::point *p3, mesh3d::point *p4, mesh3d::point *p5, mesh3d::point *p6)
00081 {
00082     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5, p6);
00083 }
00084 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0, mesh3d::point *p1, mesh3d::point *p2, mesh3d::point *p3, mesh3d::point *p4, mesh3d::point *p5, mesh3d::point *p6, mesh3d::point *p7)
00085 {
00086     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5, p6, p7);
00087 }
00088 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0, mesh3d::point *p1, mesh3d::point *p2, mesh3d::point *p3, mesh3d::point *p4, mesh3d::point *p5, mesh3d::point *p6, mesh3d::point *p7, mesh3d::point *p8)
00089 {
00090     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5, p6, p7, p8);
00091 }
00092 mesh3d::polygon *polymesh::make_polygon(mesh3d::point *p0, mesh3d::point *p1, mesh3d::point *p2, mesh3d::point *p3, mesh3d::point *p4, mesh3d::point *p5, mesh3d::point *p6, mesh3d::point *p7, mesh3d::point *p8, mesh3d::point *p9)
00093 {
00094     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
00095 }
00096 
00097 mesh3d::polygon *polymesh::make_polygon(size_t p0)
00098 {
00099     return m_geometry.make_polygon(p0);
00100 }
00101 mesh3d::polygon *polymesh::make_polygon(size_t p0, size_t p1)
00102 {
00103     return m_geometry.make_polygon(p0, p1);
00104 }
00105 mesh3d::polygon *polymesh::make_polygon(size_t p0, size_t p1, size_t p2)
00106 {
00107     return m_geometry.make_polygon(p0, p1, p2);
00108 }
00109 mesh3d::polygon *polymesh::make_polygon(size_t p0, size_t p1, size_t p2, size_t p3)
00110 {
00111     return m_geometry.make_polygon(p0, p1, p2, p3);
00112 }
00113 mesh3d::polygon *polymesh::make_polygon(size_t p0, size_t p1, size_t p2, size_t p3, size_t p4)
00114 {
00115     return m_geometry.make_polygon(p0, p1, p2, p3, p4);
00116 }
00117 mesh3d::polygon *polymesh::make_polygon(size_t p0, size_t p1, size_t p2, size_t p3, size_t p4, size_t p5)
00118 {
00119     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5);
00120 }
00121 mesh3d::polygon *polymesh::make_polygon(size_t p0, size_t p1, size_t p2, size_t p3, size_t p4, size_t p5, size_t p6)
00122 {
00123     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5, p6);
00124 }
00125 mesh3d::polygon *polymesh::make_polygon(size_t p0, size_t p1, size_t p2, size_t p3, size_t p4, size_t p5, size_t p6, size_t p7)
00126 {
00127     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5, p6, p7);
00128 }
00129 mesh3d::polygon *polymesh::make_polygon(size_t p0, size_t p1, size_t p2, size_t p3, size_t p4, size_t p5, size_t p6, size_t p7, size_t p8)
00130 {
00131     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5, p6, p7, p8);
00132 }
00133 mesh3d::polygon *polymesh::make_polygon(size_t p0, size_t p1, size_t p2, size_t p3, size_t p4, size_t p5, size_t p6, size_t p7, size_t p8, size_t p9)
00134 {
00135     return m_geometry.make_polygon(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
00136 }
00137 
00138 void polymesh::fix_normals()
00139 {
00140     mesh3d::geometry &g = m_geometry;
00141 
00142     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_normals = g.polygon_attributes().find<mesh3d::vec3>("polygon_normals");
00143     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*,   mesh3d::vec3> > point_locations = g.point_attributes  ().find<mesh3d::vec3>("point_locations");
00144 
00145     mesh3d::geometry::polygon_collection &polygons = g.polygons();
00146 
00147     bool recompute_needed = false;
00148 
00149     for(
00150         mesh3d::geometry::polygon_collection::iterator i = polygons.begin();
00151         i != polygons.end();
00152         ++i
00153     )
00154     {
00155         mesh3d::polygon *pol = *i;
00156         if(pol->corners().size() < 3)
00157         {
00158             continue;
00159         }
00160         mesh3d::vec3    pn = polygon_normals->value(pol);
00161         mesh3d::corner  *first_corner       = *pol->corners().begin();
00162         mesh3d::point   *first_point        = first_corner->point();
00163         mesh3d::vec3    reference_location  = point_locations->value(first_point);
00164 
00165         float d = dot(pn, reference_location);
00166 
00167         if(d < 0)
00168         {
00169             pol->reverse();
00170             recompute_needed = true;
00171         }
00172     }
00173 
00174     if(recompute_needed == true)
00175     {
00176         g.compute_polygon_normals();
00177     }
00178 }
00179 
00180 
00181 
00182 
00183 struct edge
00184 {
00185 public:
00186     edge(mesh3d::point *p0, mesh3d::point *p1)
00187     {
00188         if(p0 < p1)
00189         {
00190             m_pair.first  = p0;
00191             m_pair.second = p1;
00192         }
00193         else
00194         {
00195             m_pair.first  = p1;
00196             m_pair.second = p0;
00197         }
00198     }
00199 
00200     bool operator<(edge const &other) const
00201     {
00202         return m_pair < other.m_pair;
00203     }
00204 
00205     std::pair<mesh3d::point*, mesh3d::point*> m_pair;
00206 };
00207 
00208 /*  Compute normals  */ 
00209 /*  Unify normal directions - currently only works for convex polyhedra  */ 
00210 /*  Setup mesh with                */ 
00211 /*    position                     */ 
00212 /*    smoothed corner normals      */ 
00213 /*    polygon face normals         */ 
00214 /*    per vertex polygon ids       */ 
00215 /*  Create all vertices and index buffers for  */ 
00216 /*    corner points                */ 
00217 /*    centroid points              */ 
00218 /*    polygon edges                */ 
00219 /*    polygon triangles            */ 
00220 void polymesh::build_mesh_from_geometry(bool fix_convex_normals)
00221 {
00222     mesh3d::geometry &g = m_geometry;
00223     /*                                                                                    */ 
00224     /*  FIRST: Figure out what sources we have, and compute some if necessary / possible  */ 
00225     /*                                                                                    */ 
00226 
00227     /*  If polygon centroids or normals are not present, the can be computed  */ 
00228     if(g.polygon_attributes().has("polygon_normals") == false)
00229     {
00230         g.compute_polygon_normals();
00231     }
00232 
00233     if(g.polygon_attributes().has("polygon_centroids") == false)
00234     {
00235         g.compute_polygon_centroids();
00236     }
00237 
00238     /*  Optionally, face normals can be flipped outward from the center  */ 
00239     /*  of the mesh. This only does good to convex polyhedra.            */ 
00240     if(fix_convex_normals == true)
00241     {
00242         fix_normals();
00243     }
00244 
00245     /*  Polygon ID's are always generated here  */ 
00246     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::polygon*, uint32> >  polygon_ids;
00247 
00248     polygon_ids = g.polygon_attributes().find_or_create<uint32>("polygon_ids");
00249 
00250     /*  Corner normals are generated, if no corner or  */ 
00251     /*  point normals are available so far.            */ 
00252     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::corner*, mesh3d::vec3> > corner_normals;
00253     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*,  mesh3d::vec3> > point_normals;
00254     if(g.corner_attributes().has("corner_normals") == true)
00255     {
00256         corner_normals = g.corner_attributes().find_or_create<mesh3d::vec3>("corner_normals");
00257     }
00258     else if(g.point_attributes().has("point_normals") == true)
00259     {
00260         point_normals = g.point_attributes().find_or_create<mesh3d::vec3>("point_normals");
00261     }
00262     else
00263     {
00264         g.compute_corner_normals(RS_TWO_PI);
00265         corner_normals = g.corner_attributes().find_or_create<mesh3d::vec3>("corner_normals");
00266     }
00267 
00268     /*  Texcoords are processed if found for corners or points, in that order  */ 
00269     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*,   mesh3d::vec2> > point_texcoords;
00270     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::corner*,  mesh3d::vec2> > corner_texcoords;
00271     if(g.corner_attributes().has("corner_texcoords") == true)
00272     {
00273         corner_texcoords = g.corner_attributes().find_or_create<mesh3d::vec2>("corner_texcoords");
00274     }
00275     else if(g.point_attributes().has("point_texcoords") == true)
00276     {
00277         point_texcoords = g.point_attributes().find_or_create<mesh3d::vec2>("point_texcoords");
00278     }
00279 
00280     /*  These should now be there  */ 
00281     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_normals;
00282     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_centroids;
00283     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*,   mesh3d::vec3> > point_locations;
00284 
00285     polygon_normals   = g.polygon_attributes().find<mesh3d::vec3>("polygon_normals");
00286     polygon_centroids = g.polygon_attributes().find<mesh3d::vec3>("polygon_centroids");
00287     point_locations   = g.point_attributes  ().find<mesh3d::vec3>("point_locations");
00288 
00289     /*  Corner indices are always generated here  */ 
00290     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::corner*, int> > corner_indices;
00291 
00292     corner_indices = g.corner_attributes ().find_or_create<int>("corner_indices");
00293 
00294     /*                                       */ 
00295     /*  SECOND: Prepare buffers for writing  */ 
00296     /*                                       */ 
00297 
00298     /*  Setup vertex format  */ 
00299     vertex_attribute  attribute_position(vertex_attribute_usage_position, GL_FLOAT,        0, 3);
00300     vertex_attribute  attribute_normal  (vertex_attribute_usage_normal,   GL_FLOAT,        0, 3);
00301     vertex_attribute  attribute_normal2 (vertex_attribute_usage_normal,   GL_FLOAT,        1, 3);
00302     vertex_attribute  attribute_texcoord(vertex_attribute_usage_texcoord, GL_FLOAT,        0, 2);
00303     vertex_attribute  attribute_id      (vertex_attribute_usage_id,       GL_UNSIGNED_INT, 0, 1);
00304 
00305     buffer *vertex_buffer = mesh::vertex_buffer();
00306     vertex_buffer->vertex_format().append(attribute_position);
00307     vertex_buffer->vertex_format().append(attribute_normal);
00308     vertex_buffer->vertex_format().append(attribute_normal2);
00309     vertex_buffer->vertex_format().append(attribute_id);
00310     if(corner_texcoords || point_texcoords)
00311     {
00312         vertex_buffer->vertex_format().append(attribute_texcoord);
00313     }
00314 
00315     buffer* polygon_fill_indices     = mesh::find_or_create_index_buffer(mesh_mode_polygon_fill     , GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, GL_UNSIGNED_INT, GL_TRIANGLES);
00316     buffer* edge_line_indices        = mesh::find_or_create_index_buffer(mesh_mode_edge_lines       , GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, GL_UNSIGNED_INT, GL_LINES);
00317     buffer* corner_point_indices     = mesh::find_or_create_index_buffer(mesh_mode_corner_points    , GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, GL_UNSIGNED_INT, GL_POINTS);
00318     buffer* polygon_centroid_indices = mesh::find_or_create_index_buffer(mesh_mode_polygon_centroids, GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, GL_UNSIGNED_INT, GL_POINTS);
00319 
00320     /*  Prepare writing to buffers  */ 
00321     vertex_buffer           ->begin_edit();
00322     polygon_fill_indices    ->begin_edit();
00323     edge_line_indices       ->begin_edit();
00324     corner_point_indices    ->begin_edit();
00325     polygon_centroid_indices->begin_edit();
00326 
00327     int index = 0;
00328     int vertex_index[mesh_mode_count] = {};
00329 
00330     /*  Edges are collected to this work database while working through  */ 
00331     /*  polygons.                                                        */ 
00332     std::set<edge> edges;
00333 
00334     uint32 polygon_index = 0;
00335     mesh3d::geometry::polygon_collection &polygons = g.polygons();
00336 
00337     /*  Go through polygons, create triangles, collect edges  */ 
00338     for(
00339         mesh3d::geometry::polygon_collection::iterator i = polygons.begin();
00340         i != polygons.end();
00341         ++i
00342     )
00343     {
00344         mesh3d::polygon *pol        = *i;
00345         mesh3d::vec3    pn;
00346         if(pol->corners().size() > 2)
00347         {
00348             pn          = polygon_normals->value(pol);
00349         }
00350         else
00351         {
00352             pn          = mesh3d::vec3(0.0f, 1.0f, 0.0f);
00353         }
00354         int             first_index = index;
00355         int             prev_index  = -1;
00356 
00357         mesh3d::corner  *first_corner       = *pol->corners().begin();
00358         mesh3d::corner  *last_corner        = *pol->corners().rbegin();
00359         mesh3d::point   *first_point        = first_corner->point();
00360         mesh3d::point   *last_point         = last_corner->point();
00361         mesh3d::point   *prev_point         = NULL;
00362         mesh3d::vec3    reference_location  = point_locations->value(first_point);
00363 
00364         for
00365         (
00366             mesh3d::polygon::corner_collection::iterator j = pol->corners().begin();
00367             j != pol->corners().end();
00368             ++j
00369         )
00370         {
00371             mesh3d::corner *cor = *j;
00372             mesh3d::point  *pnt = cor->point();
00373             mesh3d::vec3   p    = point_locations->value(pnt);
00374 
00375             /*  Set vertex attributes  */ 
00376             vertex_buffer->set_index(index); 
00377             vertex_buffer->put_position(p.x, p.y, p.z);
00378 
00379             if(corner_normals && pol->corners().size() > 2)
00380             {
00381                 mesh3d::vec3 n = corner_normals->value(cor);
00382 
00383                 vertex_buffer->put_normal(n.x, n.y, n.z);
00384             }
00385             else if(point_normals)
00386             {
00387                 mesh3d::vec3 n = point_normals->value(pnt);
00388 
00389                 vertex_buffer->put_normal(n.x, n.y, n.z);
00390             }
00391             else
00392             {
00393                 vertex_buffer->put_normal(0.0f, 1.0f, 0.0f);
00394             }
00395 
00396             vertex_buffer->put_normal(pn.x, pn.y, pn.z, 1);
00397 
00398             if(corner_texcoords)
00399             {
00400                 mesh3d::vec2 texcoord = corner_texcoords->value(cor);
00401                 vertex_buffer->put_texcoord(texcoord.x, texcoord.y);
00402             }
00403             else if(point_texcoords)
00404             {
00405                 mesh3d::vec2 texcoord = point_texcoords->value(pnt);
00406                 vertex_buffer->put_texcoord(texcoord.x, texcoord.y);
00407             }
00408 
00409             vertex_buffer->put_uint32(attribute_id, polygon_index);
00410 
00411             /*  Store polygon index to geometry database  */ 
00412             polygon_ids->set_value(pol, polygon_index);
00413 
00414             /*  Write corner point index buffer */ 
00415             corner_point_indices->set_index(
00416                 vertex_index[mesh_mode_corner_points]
00417             );
00418             corner_point_indices->point(index);
00419             ++vertex_index[mesh_mode_corner_points];
00420 
00421             /*  Store corner index to geometry database  */ 
00422             corner_indices->set_value(cor, index);
00423 
00424             /*  Write polygon fill triangle  */ 
00425             if(prev_index != -1)
00426             {
00427                 polygon_fill_indices->set_index(
00428                     vertex_index[mesh_mode_polygon_fill]
00429                 );
00430                 polygon_fill_indices->triangle(
00431                     first_index,
00432                     index,
00433                     prev_index
00434                 );
00435                 vertex_index[mesh_mode_polygon_fill] += 3;
00436             }
00437 
00438             /*  Store edge line to working database  */ 
00439             if(prev_point != NULL)
00440             {
00441                 edge e(prev_point, pnt);
00442                 edges.insert(e);
00443             }
00444 
00445             prev_index = index;
00446             prev_point = pnt;
00447 
00448             ++index;
00449         }
00450 
00451         /*  Add last edge to working database  */ 
00452         {
00453             edge e(last_point, first_point);
00454             edges.insert(e);
00455         }
00456 
00457         ++polygon_index;
00458     }
00459 
00460     /*  Write all edge lines from working database  */ 
00461     for(
00462         std::set<edge>::iterator k = edges.begin();
00463         k != edges.end();
00464         ++k
00465     )
00466     {
00467         edge            &e = *k;
00468         mesh3d::corner  *c0 = e.m_pair.first->corners().front();
00469         mesh3d::corner  *c1 = e.m_pair.second->corners().front();
00470         int             i0  = corner_indices->value(c0);
00471         int             i1  = corner_indices->value(c1);
00472         edge_line_indices->set_index(
00473             vertex_index[mesh_mode_edge_lines]
00474         );
00475         edge_line_indices->line(i0, i1);
00476         vertex_index[mesh_mode_edge_lines] += 2;
00477     }
00478 
00479     /*  Generate polygon centroid vertices and index buffer  */ 
00480     for(
00481         mesh3d::geometry::polygon_collection::iterator i = polygons.begin();
00482         i != polygons.end();
00483         ++i
00484     )
00485     {
00486         mesh3d::polygon *pol = *i;
00487         mesh3d::vec3    n;
00488         if(pol->corners().size() > 2)
00489         {
00490             n    = polygon_normals->value(pol);
00491         }
00492         else
00493         {
00494             n = mesh3d::vec3(0.0f, 1.0f, 0.0f);
00495         }
00496         mesh3d::vec3    p    = polygon_centroids->value(pol);
00497 
00498         vertex_buffer->set_index   (index); 
00499         vertex_buffer->put_position(p.x, p.y, p.z);
00500         vertex_buffer->put_normal  (n.x, n.y, n.z, 0);
00501         vertex_buffer->put_normal  (n.x, n.y, n.z, 1);
00502 
00503         polygon_centroid_indices->set_index(
00504             vertex_index[mesh_mode_polygon_centroids]
00505         );
00506         polygon_centroid_indices->point(index);
00507         ++index;
00508         ++vertex_index[mesh_mode_polygon_centroids];
00509     }
00510 
00511     vertex_buffer           ->end_edit(index);
00512     polygon_fill_indices    ->end_edit(vertex_index[mesh_mode_polygon_fill     ]);
00513     edge_line_indices       ->end_edit(vertex_index[mesh_mode_edge_lines       ]);
00514     corner_point_indices    ->end_edit(vertex_index[mesh_mode_corner_points    ]);
00515     polygon_centroid_indices->end_edit(vertex_index[mesh_mode_polygon_centroids]);
00516 }
00517 
00518 mesh *polymesh::make_mesh_from_set_of_polygons(
00519     std::set<uint32> const &polygon_indices
00520 )
00521 {
00522     mesh3d::geometry &g = m_geometry;
00523     mesh3d::geometry sub_g;
00524 
00525     /*                                                                                    */ 
00526     /*  FIRST: Figure out what sources we have, and compute some if necessary / possible  */ 
00527     /*                                                                                    */ 
00528 
00529 #if 0  //  not done for submesh
00530     /*  If polygon centroids or normals are not present, the can be computed  */ 
00531     if(g.polygon_attributes().has("polygon_normals") == false)
00532     {
00533         g.compute_polygon_normals();
00534     }
00535 
00536     if(g.polygon_attributes().has("polygon_centroids") == false)
00537     {
00538         g.compute_polygon_centroids();
00539     }
00540 #endif
00541 
00542     /*  Polygon ID's are always generated here  */ 
00543     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::polygon*, uint32> >  polygon_ids;
00544 
00545     //polygon_ids = g.polygon_attributes().find_or_create<uint32>("polygon_ids");
00546     polygon_ids = g.polygon_attributes().find<uint32>("polygon_ids");
00547 
00548     /*  Corner normals are generated, if no corner or  */ 
00549     /*  point normals are available so far.            */ 
00550     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::corner*, mesh3d::vec3> > corner_normals;
00551     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*,  mesh3d::vec3> > point_normals;
00552     if(g.corner_attributes().has("corner_normals") == true)
00553     {
00554         //corner_normals = g.corner_attributes().find_or_create<mesh3d::vec3>("corner_normals");
00555         corner_normals = g.corner_attributes().find<mesh3d::vec3>("corner_normals");
00556     }
00557     else if(g.point_attributes().has("point_normals") == true)
00558     {
00559         //point_normals = g.point_attributes().find_or_create<mesh3d::vec3>("point_normals");
00560         point_normals = g.point_attributes().find<mesh3d::vec3>("point_normals");
00561     }
00562     else
00563     {
00564         //g.compute_corner_normals(RS_TWO_PI);
00565         //corner_normals = g.corner_attributes().find_or_create<mesh3d::vec3>("corner_normals");
00566         corner_normals = g.corner_attributes().find<mesh3d::vec3>("corner_normals");
00567     }
00568 
00569     /*  Texcoords are processed if found for corners or points, in that order  */ 
00570     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*,   mesh3d::vec2> > point_texcoords;
00571     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::corner*,  mesh3d::vec2> > corner_texcoords;
00572     if(g.corner_attributes().has("corner_texcoords") == true)
00573     {
00574         //corner_texcoords = g.corner_attributes().find_or_create<mesh3d::vec2>("corner_texcoords");
00575         corner_texcoords = g.corner_attributes().find<mesh3d::vec2>("corner_texcoords");
00576     }
00577     else if(g.point_attributes().has("point_texcoords") == true)
00578     {
00579         //point_texcoords = g.point_attributes().find_or_create<mesh3d::vec2>("point_texcoords");
00580         point_texcoords = g.point_attributes().find<mesh3d::vec2>("point_texcoords");
00581     }
00582 
00583     /*  These should now be there  */ 
00584     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_normals;
00585     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_centroids;
00586     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*,   mesh3d::vec3> > point_locations;
00587 
00588     polygon_normals   = g.polygon_attributes().find<mesh3d::vec3>("polygon_normals");
00589     polygon_centroids = g.polygon_attributes().find<mesh3d::vec3>("polygon_centroids");
00590     point_locations   = g.point_attributes  ().find<mesh3d::vec3>("point_locations");
00591 
00592     /*  Corner indices are always generated here  */ 
00593     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::corner*, int> > corner_indices;
00594 
00595     //corner_indices = g.corner_attributes().find_or_create<int>("corner_indices");
00596     corner_indices = sub_g.corner_attributes().find_or_create<int>("corner_indices");
00597 
00598 #if 1
00599     /*  Point indices are? needed? when making submeshes  */ 
00600     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*, int> > point_indices;
00601     point_indices = sub_g.point_attributes().find_or_create<int>("point_indices");
00602 #endif
00603 
00604     /*                                       */ 
00605     /*  SECOND: Prepare buffers for writing  */ 
00606     /*                                       */ 
00607 
00608     /*  Setup vertex format  */ 
00609     vertex_attribute  attribute_position(vertex_attribute_usage_position, GL_FLOAT,        0, 3);
00610     vertex_attribute  attribute_normal  (vertex_attribute_usage_normal,   GL_FLOAT,        0, 3);
00611     vertex_attribute  attribute_normal2 (vertex_attribute_usage_normal,   GL_FLOAT,        1, 3);
00612     vertex_attribute  attribute_texcoord(vertex_attribute_usage_texcoord, GL_FLOAT,        0, 2);
00613     vertex_attribute  attribute_id      (vertex_attribute_usage_id,       GL_UNSIGNED_INT, 0, 1);
00614 
00615     mesh *submesh = new mesh();
00616     buffer *vertex_buffer = submesh->vertex_buffer();
00617     vertex_buffer->vertex_format().append(attribute_position);
00618     vertex_buffer->vertex_format().append(attribute_normal);
00619     vertex_buffer->vertex_format().append(attribute_normal2);
00620     vertex_buffer->vertex_format().append(attribute_id);
00621     if(corner_texcoords || point_texcoords)
00622     {
00623         vertex_buffer->vertex_format().append(attribute_texcoord);
00624     }
00625 
00626     buffer* polygon_fill_indices     = submesh->find_or_create_index_buffer(mesh_mode_polygon_fill     , GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, GL_UNSIGNED_INT, GL_TRIANGLES);
00627     buffer* edge_line_indices        = submesh->find_or_create_index_buffer(mesh_mode_edge_lines       , GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, GL_UNSIGNED_INT, GL_LINES);
00628     buffer* corner_point_indices     = submesh->find_or_create_index_buffer(mesh_mode_corner_points    , GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, GL_UNSIGNED_INT, GL_POINTS);
00629     buffer* polygon_centroid_indices = submesh->find_or_create_index_buffer(mesh_mode_polygon_centroids, GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, GL_UNSIGNED_INT, GL_POINTS);
00630 
00631     /*  Prepare writing to buffers  */ 
00632     vertex_buffer           ->begin_edit();
00633     polygon_fill_indices    ->begin_edit();
00634     edge_line_indices       ->begin_edit();
00635     corner_point_indices    ->begin_edit();
00636     polygon_centroid_indices->begin_edit();
00637 
00638     int index = 0;
00639     int vertex_index[mesh_mode_count] = {};
00640 
00641     /*  Edges are collected to this work database while working through  */ 
00642     /*  polygons.                                                        */ 
00643     std::set<edge> edges;
00644 
00645     uint32 polygon_index = 0;
00646     //mesh3d::geometry::polygon_collection &polygons = g.polygons();
00647 
00648     /*  Go through polygons, create triangles, collect edges  */ 
00649     for(
00650         std::set<uint32>::const_iterator i = polygon_indices.begin();
00651         i != polygon_indices.end();
00652         ++i
00653     )
00654     {
00655         mesh3d::polygon *pol        = g.polygons()[*i];
00656         mesh3d::vec3    pn          = polygon_normals->value(pol);
00657         int             first_index = index;
00658         int             prev_index  = -1;
00659 
00660         mesh3d::corner  *first_corner       = *pol->corners().begin();
00661         mesh3d::corner  *last_corner        = *pol->corners().rbegin();
00662         mesh3d::point   *first_point        = first_corner->point();
00663         mesh3d::point   *last_point         = last_corner->point();
00664         mesh3d::point   *prev_point         = NULL;
00665         mesh3d::vec3    reference_location  = point_locations->value(first_point);
00666 
00667         for
00668         (
00669             mesh3d::polygon::corner_collection::iterator j = pol->corners().begin();
00670             j != pol->corners().end();
00671             ++j
00672         )
00673         {
00674             mesh3d::corner *cor = *j;
00675             mesh3d::point  *pnt = cor->point();
00676             mesh3d::vec3   p    = point_locations->value(pnt);
00677 
00678             /*  Set vertex attributes  */ 
00679             vertex_buffer->set_index(index); 
00680             vertex_buffer->put_position(p.x, p.y, p.z);
00681 
00682             if(corner_normals)
00683             {
00684                 mesh3d::vec3 n = corner_normals->value(cor);
00685 
00686                 vertex_buffer->put_normal(n.x, n.y, n.z);
00687             }
00688             else if(point_normals)
00689             {
00690                 mesh3d::vec3 n = point_normals->value(pnt);
00691 
00692                 vertex_buffer->put_normal(n.x, n.y, n.z);
00693             }
00694 
00695             vertex_buffer->put_normal(pn.x, pn.y, pn.z, 1);
00696 
00697             if(corner_texcoords)
00698             {
00699                 mesh3d::vec2 texcoord = corner_texcoords->value(cor);
00700                 vertex_buffer->put_texcoord(texcoord.x, texcoord.y);
00701             }
00702             else if(point_texcoords)
00703             {
00704                 mesh3d::vec2 texcoord = point_texcoords->value(pnt);
00705                 vertex_buffer->put_texcoord(texcoord.x, texcoord.y);
00706             }
00707 
00708             vertex_buffer->put_uint32(attribute_id, polygon_index);
00709 
00710 #if 0  //  not done for submesh
00711             /*  Store polygon index to geometry database  */ 
00712             polygon_ids->set_value(pol, polygon_index);
00713 #endif
00714 
00715             /*  Write corner point index buffer */ 
00716             corner_point_indices->set_index(
00717                 vertex_index[mesh_mode_corner_points]
00718             );
00719             corner_point_indices->point(index);
00720             ++vertex_index[mesh_mode_corner_points];
00721 
00722             /*  Store corner index to geometry database  */ 
00723             corner_indices->set_value(cor, index);
00724             point_indices->set_value(pnt, index);
00725 
00726             /*  Write polygon fill triangle  */ 
00727             if(prev_index != -1)
00728             {
00729                 polygon_fill_indices->set_index(
00730                     vertex_index[mesh_mode_polygon_fill]
00731                 );
00732                 polygon_fill_indices->triangle(
00733                     first_index,
00734                     index,
00735                     prev_index
00736                 );
00737                 vertex_index[mesh_mode_polygon_fill] += 3;
00738             }
00739 
00740             /*  Store edge line to working database  */ 
00741             if(prev_point != NULL)
00742             {
00743                 edge e(prev_point, pnt);
00744                 edges.insert(e);
00745             }
00746 
00747             prev_index = index;
00748             prev_point = pnt;
00749 
00750             ++index;
00751         }
00752 
00753         /*  Add last edge to working database  */ 
00754         {
00755             edge e(last_point, first_point);
00756             edges.insert(e);
00757         }
00758 
00759         ++polygon_index;
00760     }
00761 
00762     /*  Write all edge lines from working database  */ 
00763     for(
00764         std::set<edge>::iterator k = edges.begin();
00765         k != edges.end();
00766         ++k
00767     )
00768     {
00769         edge            &e = *k;
00770 #if 0
00771         mesh3d::corner  *c0 = e.m_pair.first->corners().front();
00772         mesh3d::corner  *c1 = e.m_pair.second->corners().front();
00773         int             i0  = corner_indices->value(c0);
00774         int             i1  = corner_indices->value(c1);
00775 #endif
00776         int             i0  = point_indices->value(e.m_pair.first);
00777         int             i1  = point_indices->value(e.m_pair.second);
00778 
00779         edge_line_indices->set_index(
00780             vertex_index[mesh_mode_edge_lines]
00781         );
00782         edge_line_indices->line(i0, i1);
00783         vertex_index[mesh_mode_edge_lines] += 2;
00784     }
00785 
00786     /*  Generate polygon centroid vertices and index buffer  */ 
00787     for(
00788         std::set<uint32>::const_iterator i = polygon_indices.begin();
00789         i != polygon_indices.end();
00790         ++i
00791     )
00792     {
00793         mesh3d::polygon *pol    = g.polygons()[*i];
00794         mesh3d::vec3    n       = polygon_normals->value(pol);
00795         mesh3d::vec3    p       = polygon_centroids->value(pol);
00796 
00797         vertex_buffer->set_index   (index); 
00798         vertex_buffer->put_position(p.x, p.y, p.z);
00799         vertex_buffer->put_normal  (n.x, n.y, n.z, 0);
00800         vertex_buffer->put_normal  (n.x, n.y, n.z, 1);
00801 
00802         polygon_centroid_indices->set_index(
00803             vertex_index[mesh_mode_polygon_centroids]
00804         );
00805         polygon_centroid_indices->point(index);
00806         ++index;
00807         ++vertex_index[mesh_mode_polygon_centroids];
00808     }
00809 
00810     vertex_buffer           ->end_edit(index);
00811     polygon_fill_indices    ->end_edit(vertex_index[mesh_mode_polygon_fill     ]);
00812     edge_line_indices       ->end_edit(vertex_index[mesh_mode_edge_lines       ]);
00813     corner_point_indices    ->end_edit(vertex_index[mesh_mode_corner_points    ]);
00814     polygon_centroid_indices->end_edit(vertex_index[mesh_mode_polygon_centroids]);
00815 
00816     return submesh;
00817 }
00818 
00819 mesh3d::point *sphere::make_point(
00820     double rel_slice, 
00821     double rel_stack, 
00822     double radius
00823 )
00824 {
00825     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*, mesh3d::vec3> > point_locations;
00826     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*, mesh3d::vec3> > point_normals;
00827     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*, mesh3d::vec2> > point_texcoords;
00828 
00829     mesh3d::geometry &g = m_geometry;
00830     point_locations = g.point_attributes().find_or_create<mesh3d::vec3>("point_locations");
00831     point_normals   = g.point_attributes().find_or_create<mesh3d::vec3>("point_normals");
00832     point_texcoords = g.point_attributes().find_or_create<mesh3d::vec2>("point_texcoords");
00833 
00834     double  phi             = (RS_TWO_PI * rel_slice);
00835     double  sin_phi         = std::sin(phi);
00836     double  cos_phi         = std::cos(phi);
00837 
00838     double  theta           = (RS_HALF_PI * rel_stack);
00839     double  sin_theta       = std::sin(theta);
00840     double  cos_theta       = std::cos(theta);
00841 
00842     double  stack_radius    = cos_theta;
00843 
00844     float   xVN             = (float)(stack_radius * cos_phi);
00845     float   yVN             = (float)(sin_theta);
00846     float   zVN             = (float)(stack_radius * sin_phi);
00847 
00848     float   xP              = (float)(radius * xVN);
00849     float   yP              = (float)(radius * yVN);
00850     float   zP              = (float)(radius * zVN);
00851 
00852     float   s               = (float)(rel_slice);
00853     float   t               = (float)(0.5f * (1.0f + rel_stack));
00854 
00855     mesh3d::point* pnt = g.make_point();
00856 
00857     point_locations->set_value(pnt, mesh3d::vec3(xP, yP, zP));
00858     point_normals  ->set_value(pnt, mesh3d::vec3(xVN, yVN, zVN));
00859     point_texcoords->set_value(pnt, mesh3d::vec2(s, t));
00860 
00861     return pnt;
00862 }
00863 
00864 
00865 /*  Classic slices and stacks sphere                          */ 
00866 /*  Note that lines rel_slice == 0 and rel_slice == 1 have    */ 
00867 /*  separate vertices on purpose, as they have different      */ 
00868 /*  texcoords.                                                */ 
00869 /*  Also note that bottom and top fans are made of triangles  */ 
00870 /*  instead of quads, and interpolation of texcoords will     */ 
00871 /*  just fail there. If you texture map a sphere, make sure   */ 
00872 /*  the polar fans have unified texel color.                  */ 
00873 sphere::sphere(float radius, int stack_division, int slice_count)
00874 {
00875     int stack_count = (2 * stack_division) + 1;
00876 
00877     int slice;
00878     int stack;
00879 
00880     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*,   mesh3d::vec3> > point_locations;
00881     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::point*,   mesh3d::vec3> > point_normals;
00882     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_centroids;
00883     std::tr1::shared_ptr<mesh3d::attribute_map<mesh3d::polygon*, mesh3d::vec3> > polygon_normals;
00884 
00885     mesh3d::geometry &g = m_geometry;
00886     point_locations   = g.point_attributes  ().find_or_create<mesh3d::vec3>("point_locations");
00887     point_normals     = g.point_attributes  ().find_or_create<mesh3d::vec3>("point_normals");
00888     polygon_centroids = g.polygon_attributes().find_or_create<mesh3d::vec3>("polygon_centroids");
00889     polygon_normals   = g.polygon_attributes().find_or_create<mesh3d::vec3>("polygon_normals");
00890 
00891     /*  Bottom and top vertices  */ 
00892     mesh3d::point *bottom = make_point(0.5f, -1.0f, radius);
00893     mesh3d::point *top    = make_point(0.5f, 1.0f, radius);
00894 
00895     /*  Other vertices  */ 
00896     std::vector<mesh3d::point*> points;
00897     for(slice = 0; slice <= slice_count; ++slice)
00898     {
00899         double rel_slice = (double)(slice) / (double)(slice_count);
00900         for(stack = -stack_division; stack <= stack_division; ++stack)
00901         {
00902             double rel_stack = (double)(stack) / (double)(stack_division + 1);
00903 
00904             mesh3d::point *pnt = make_point(rel_slice, rel_stack, radius);
00905 
00906             points.push_back(pnt);
00907         }
00908     }
00909 
00910     /*  Bottom fan  */ 
00911     std::vector<mesh3d::point*> centroids;
00912     {
00913         for(slice = 0; slice < slice_count; ++slice)
00914         {
00915             int next_slice  = (slice + 1);
00916             int stack_base0 = 0;
00917 
00918             double rel_slice = ((double)(slice) + 0.5) / (double)(slice_count);
00919             double rel_stack = 0.5 / (double)(stack_division + 1);
00920 
00921             mesh3d::point *centroid = make_point(rel_slice, rel_stack, radius);
00922 
00923             mesh3d::polygon *pol = g.make_polygon(
00924                 points[(slice      * stack_count) + stack_base0],
00925                 bottom,
00926                 points[(next_slice * stack_count) + stack_base0]
00927             );
00928 
00929             polygon_centroids->set_value(pol, point_locations->value(centroid));
00930             polygon_normals  ->set_value(pol, point_normals  ->value(centroid));
00931         }
00932     }
00933 
00934     /*  Middle quads, bottom up  */ 
00935     for(
00936         stack = -stack_division; 
00937         stack < stack_division; 
00938         ++stack
00939     )
00940     {
00941         int stack_base0      = stack + stack_division;
00942         int next_stack_base0 = stack_base0 + 1;
00943 
00944         double rel_stack = ((double)(stack) + 0.5) / (double)(stack_division + 1);
00945 
00946         for(slice = 0; slice < slice_count; ++slice)
00947         {
00948             int next_slice = (slice + 1);
00949 
00950             double rel_slice = ((double)(slice) + 0.5) / (double)(slice_count);
00951 
00952             mesh3d::point *centroid = make_point(rel_slice, rel_stack, radius);
00953 
00954             mesh3d::polygon *pol = g.make_polygon(
00955                 points[(next_slice * stack_count) + next_stack_base0],
00956                 points[(slice      * stack_count) + next_stack_base0],
00957                 points[(slice      * stack_count) + stack_base0],
00958                 points[(next_slice * stack_count) + stack_base0]
00959             );
00960 
00961             polygon_centroids->set_value(pol, point_locations->value(centroid));
00962             polygon_normals  ->set_value(pol, point_normals  ->value(centroid));
00963         }
00964     }
00965 
00966     /*  Top fan   */ 
00967     for(slice = 0; slice < slice_count; ++slice)
00968     {
00969         int next_slice  = (slice + 1);
00970         int stack       =  stack_division;
00971         int stack_base0 =  stack + stack_division;
00972 
00973         double rel_slice = ((double)(slice) + 0.5) / (double)(slice_count);
00974         double rel_stack = 1.0 - (0.5 / (double)(stack_division + 1));
00975 
00976         mesh3d::point *centroid = make_point(rel_slice, rel_stack, radius);
00977 
00978         mesh3d::polygon *pol = g.make_polygon(
00979             top,
00980             points[(slice      * stack_count) + stack_base0],
00981             points[(next_slice * stack_count) + stack_base0]
00982         );
00983 
00984         polygon_centroids->set_value(pol, point_locations->value(centroid));
00985         polygon_normals  ->set_value(pol, point_normals  ->value(centroid));
00986     }
00987 
00988     build_mesh_from_geometry(false);
00989 }
00990 
00991 quad::quad()
00992 {
00993     push_point(0.0,  0.0,  0.0);
00994     push_point(1.0,  0.0,  0.0);
00995     push_point(1.0,  1.0,  0.0);
00996     push_point(0.0,  1.0,  0.0);
00997 
00998     make_polygon(0, 1, 2, 3);
00999 
01000     build_mesh_from_geometry();
01001 }
01002 
01003 
01004 cube::cube(double r)
01005 {
01006     push_point(-r / sq3,  r / sq3,  r / sq3);
01007     push_point( r / sq3,  r / sq3,  r / sq3);
01008     push_point( r / sq3, -r / sq3,  r / sq3);
01009     push_point(-r / sq3, -r / sq3,  r / sq3);
01010     push_point(-r / sq3,  r / sq3, -r / sq3);
01011     push_point( r / sq3,  r / sq3, -r / sq3);
01012     push_point( r / sq3, -r / sq3, -r / sq3);
01013     push_point(-r / sq3, -r / sq3, -r / sq3);
01014 
01015     make_polygon(  0, 1, 2, 3  );
01016     make_polygon(  0, 3, 7, 4  );
01017     make_polygon(  0, 4, 5, 1  );
01018     make_polygon(  6, 7, 4, 5  );
01019     make_polygon(  6, 5, 1, 2  );
01020     make_polygon(  6, 2, 3, 7  );
01021 
01022     build_mesh_from_geometry();
01023 }
01024 
01025 
01026 cuboctahedron::cuboctahedron(double r)
01027 {
01028     push_point(      0,      r,            0 );
01029     push_point(  r / 2,  r / 2,  r * sq2 / 2 );
01030     push_point(  r / 2,  r / 2, -r * sq2 / 2 );
01031     push_point(      r,      0,            0 );
01032     push_point(  r / 2, -r / 2,  r * sq2 / 2 );
01033     push_point(  r / 2, -r / 2, -r * sq2 / 2 );
01034     push_point(      0,     -r,            0 );
01035     push_point( -r / 2, -r / 2,  r * sq2 / 2 );
01036     push_point( -r / 2, -r / 2, -r * sq2 / 2 );
01037     push_point(     -r,      0,            0 );
01038     push_point( -r / 2,  r / 2,  r * sq2 / 2 );
01039     push_point( -r / 2,  r / 2, -r * sq2 / 2 );
01040 
01041     make_polygon(  1, 4,  7, 10 );
01042     make_polygon(  4, 3,  5,  6 );
01043     make_polygon(  1, 3,  2,  0 );
01044     make_polygon(  2, 5,  8, 11 );
01045     make_polygon( 10, 9, 11,  0 );
01046     make_polygon(  7, 6,  8,  9 );
01047 
01048     make_polygon(  0, 1, 10 );
01049     make_polygon(  3, 4,  1 );
01050     make_polygon(  4, 6,  7 );
01051     make_polygon( 10, 7,  9 );
01052     make_polygon(  0, 2, 11 );
01053     make_polygon(  3, 5,  2 );
01054     make_polygon(  5, 6,  8 );
01055     make_polygon( 11, 8,  9 );
01056 
01057     build_mesh_from_geometry();
01058 }
01059 
01060 dodecahedron::dodecahedron(double r)
01061 {
01062     double a = 2.0 / (sq3 + sq3 * sq5);
01063     double b = 1.0 / (3.0 * a);
01064 
01065     push_point( r / sq3,  r / sq3,  r / sq3);
01066     push_point( r / sq3,  r / sq3, -r / sq3);
01067     push_point( r / sq3, -r / sq3,  r / sq3);
01068     push_point( r / sq3, -r / sq3, -r / sq3);
01069     push_point(-r / sq3,  r / sq3,  r / sq3);
01070     push_point(-r / sq3,  r / sq3, -r / sq3);
01071     push_point(-r / sq3, -r / sq3,  r / sq3);
01072     push_point(-r / sq3, -r / sq3, -r / sq3);
01073     push_point(       0,  r * a,  r * b);
01074     push_point(       0,  r * a, -r * b);
01075     push_point(       0, -r * a,  r * b);
01076     push_point(       0, -r * a, -r * b);
01077     push_point( r * a,  r * b,        0);
01078     push_point( r * a, -r * b,        0);
01079     push_point(-r * a,  r * b,        0);
01080     push_point(-r * a, -r * b,        0);
01081     push_point( r * b,        0,  r * a);
01082     push_point( r * b,        0, -r * a);
01083     push_point(-r * b,        0,  r * a);
01084     push_point(-r * b,        0, -r * a);
01085 
01086     make_polygon( 10,  8, 4, 18, 6 );
01087     make_polygon( 10,  8, 0, 16, 2 );
01088     make_polygon( 11,  9, 1, 17, 3 );
01089     make_polygon(  9, 11, 7, 19, 5 );
01090     make_polygon( 17, 16, 2, 13, 3 );
01091     make_polygon( 17, 16, 0, 12, 1 );
01092     make_polygon( 19, 18, 6, 15, 7 );
01093     make_polygon( 19, 18, 4, 14, 5 );
01094     make_polygon( 12, 14, 4,  8, 0 );
01095     make_polygon( 12, 14, 5,  9, 1 );
01096     make_polygon( 13, 15, 6, 10, 2 );
01097     make_polygon( 13, 15, 7, 11, 3 );
01098 
01099     build_mesh_from_geometry();
01100 }
01101 
01102 icosahedron::icosahedron(double r)
01103 {
01104     double a = 2.0 / (1.0 + sq5);
01105     double b = sqrt((3.0 + sq5) / (1.0 + sq5));
01106     a /= b;
01107 
01108     push_point(      0,  r * a,  r / b );
01109     push_point(      0,  r * a, -r / b );
01110     push_point(      0, -r * a,  r / b );
01111     push_point(      0, -r * a, -r / b );
01112     push_point(  r * a,  r / b,      0 );
01113     push_point(  r * a, -r / b,      0 );
01114     push_point( -r * a,  r / b,      0 );
01115     push_point( -r * a, -r / b,      0 );
01116     push_point(  r / b,      0,  r * a );
01117     push_point(  r / b,      0, -r * a );
01118     push_point( -r / b,      0,  r * a );
01119     push_point( -r / b,      0, -r * a );
01120 
01121     make_polygon( 1,  4,  6);
01122     make_polygon( 0,  6,  4);
01123     make_polygon( 0,  2, 10);
01124     make_polygon( 0,  8,  2);
01125     make_polygon( 1,  3,  9);
01126     make_polygon( 1, 11,  3);
01127     make_polygon( 2,  5,  7);
01128     make_polygon( 3,  7,  5);
01129     make_polygon( 6, 10, 11);
01130     make_polygon( 7, 11, 10);
01131     make_polygon( 4,  9,  8);
01132     make_polygon( 5,  8,  9);
01133     make_polygon( 0, 10,  6);
01134     make_polygon( 0,  4,  8);
01135     make_polygon( 1,  6, 11);
01136     make_polygon( 1,  9,  4);
01137     make_polygon( 3, 11,  7);
01138     make_polygon( 3,  5,  9);
01139     make_polygon( 2,  7, 10);
01140     make_polygon( 2,  8,  5);
01141 
01142     build_mesh_from_geometry();
01143 }
01144 
01145 octahedron::octahedron(double r)
01146 {
01147     push_point( 0,  r,  0);
01148     push_point( 0, -r,  0);
01149     push_point(-r,  0,  0);
01150     push_point( 0,  0, -r);
01151     push_point( r,  0,  0);
01152     push_point( 0,  0,  r);
01153 
01154     make_polygon( 0, 2, 3 );
01155     make_polygon( 0, 3, 4 );
01156     make_polygon( 0, 4, 5 );
01157     make_polygon( 0, 5, 2 );
01158     make_polygon( 1, 2, 3 );
01159     make_polygon( 1, 3, 4 );
01160     make_polygon( 1, 4, 5 );
01161     make_polygon( 1, 5, 2 );
01162 
01163     build_mesh_from_geometry();
01164 }
01165 
01166 tetrahedron::tetrahedron(double r)
01167 {
01168     push_point(                 0,          r,                  0   );
01169     push_point(                 0,   -r / 3.0,  r * 2.0 * sq2 / 3.0 );
01170     push_point(-r * sq3 * sq2 / 3.0, -r / 3.0,       -r * sq2 / 3.0 );
01171     push_point( r * sq3 * sq2 / 3.0, -r / 3.0,       -r * sq2 / 3.0 );
01172 
01173     make_polygon( 0, 1, 2 );
01174     make_polygon( 0, 1, 3 );
01175     make_polygon( 0, 2, 3 );
01176     make_polygon( 1, 2, 3 );
01177 
01178     build_mesh_from_geometry();
01179 }
01180 
01181 truncated_cube::truncated_cube(double r)
01182 {
01183     double a = (1.0 + sq2) / (2.0 * sqrt(5.0 / 2.0 + sq2));
01184     double b = 1.0 / (2.0 * sqrt(5.0 / 2.0 + sq2));
01185 
01186     push_point( r * b,  r * a,  r * a);
01187     push_point( r * a,  r * b,  r * a);
01188     push_point( r * a, -r * b,  r * a);
01189     push_point( r * b, -r * a,  r * a);
01190     push_point(-r * b, -r * a,  r * a);
01191     push_point(-r * a, -r * b,  r * a);
01192     push_point(-r * a,  r * b,  r * a);
01193     push_point(-r * b,  r * a,  r * a);
01194     push_point( r * a,  r * a,  r * b);
01195     push_point( r * a, -r * a,  r * b);
01196     push_point(-r * a, -r * a,  r * b);
01197     push_point(-r * a,  r * a,  r * b);
01198     push_point( r * a,  r * a, -r * b);
01199     push_point( r * a, -r * a, -r * b);
01200     push_point(-r * a, -r * a, -r * b);
01201     push_point(-r * a,  r * a, -r * b);
01202     push_point( r * b,  r * a, -r * a);
01203     push_point( r * a,  r * b, -r * a);
01204     push_point( r * a, -r * b, -r * a);
01205     push_point( r * b, -r * a, -r * a);
01206     push_point(-r * b, -r * a, -r * a);
01207     push_point(-r * a, -r * b, -r * a);
01208     push_point(-r * a,  r * b, -r * a);
01209     push_point(-r * b,  r * a, -r * a);
01210 
01211     make_polygon(  0,  1,  8 );
01212     make_polygon(  2,  3,  9 );
01213     make_polygon(  4,  5, 10 );
01214     make_polygon(  6,  7, 11 );
01215     make_polygon( 16, 17, 12 );
01216     make_polygon( 18, 19, 13 );
01217     make_polygon( 20, 21, 14 );
01218     make_polygon( 22, 23, 15 );
01219 
01220     make_polygon(  0,  1,  2,  3,  4,  5,  6,  7 );
01221     make_polygon(  1,  2,  9, 13, 18, 17, 12,  8 );
01222     make_polygon(  3,  4, 10, 14, 20, 19, 13,  9 );
01223     make_polygon(  5,  6, 11, 15, 22, 21, 14, 10 );
01224     make_polygon(  7,  0,  8, 12, 16, 23, 15, 11 );
01225     make_polygon( 16, 17, 18, 19, 20, 21, 22, 23 );
01226 
01227     build_mesh_from_geometry();
01228 }
01229 
01230 #if 0 // this one is broken
01231 truncated_cuboctahedron::truncated_cuboctahedron(double r)
01232 {
01233     push_point(-r / (sq2 * sq3),  r / (sq2 * sq3),  r *  sq2 / sq3 );
01234     push_point( r / (sq2 * sq3),  r / (sq2 * sq3),  r *  sq2 / sq3 );
01235     push_point( r / (sq2 * sq3), -r / (sq2 * sq3),  r *  sq2 / sq3 );
01236     push_point(-r / (sq2 * sq3), -r / (sq2 * sq3),  r *  sq2 / sq3 );
01237     push_point(-r / (sq2 * sq3),  r *  sq2 / sq3 ,  r / (sq2 * sq3));
01238     push_point(-r / (sq2 * sq3),  r *  sq2 / sq3 , -r / (sq2 * sq3));
01239     push_point( r / (sq2 * sq3),  r *  sq2 / sq3 , -r / (sq2 * sq3));
01240     push_point( r / (sq2 * sq3),  r *  sq2 / sq3 ,  r / (sq2 * sq3));
01241     push_point( r *  sq2 / sq3 ,  r / (sq2 * sq3),  r / (sq2 * sq3));
01242     push_point( r *  sq2 / sq3 ,  r / (sq2 * sq3), -r / (sq2 * sq3));
01243     push_point( r *  sq2 / sq3 , -r / (sq2 * sq3), -r / (sq2 * sq3));
01244     push_point( r *  sq2 / sq3 , -r / (sq2 * sq3),  r / (sq2 * sq3));
01245     push_point( r / (sq2 * sq3),  r / (sq2 * sq3),  r / (sq2 * sq3));
01246     push_point( r / (sq2 * sq3),  r / (sq2 * sq3), -r / (sq2 * sq3));
01247     push_point(-r / (sq2 * sq3),  r / (sq2 * sq3), -r / (sq2 * sq3));
01248     push_point(-r / (sq2 * sq3),  r / (sq2 * sq3),  r / (sq2 * sq3));
01249     push_point(-r *  sq2 / sq3 , -r / (sq2 * sq3),  r / (sq2 * sq3));
01250     push_point(-r *  sq2 / sq3 , -r / (sq2 * sq3), -r / (sq2 * sq3));
01251     push_point(-r *  sq2 / sq3 ,  r / (sq2 * sq3), -r / (sq2 * sq3));
01252     push_point(-r *  sq2 / sq3 ,  r / (sq2 * sq3),  r / (sq2 * sq3));
01253     push_point(-r / (sq2 * sq3),  r / (sq2 * sq3), -r *  sq2 / sq3 );
01254     push_point( r / (sq2 * sq3),  r / (sq2 * sq3), -r *  sq2 / sq3 );
01255     push_point( r / (sq2 * sq3), -r / (sq2 * sq3), -r *  sq2 / sq3 );
01256     push_point(-r / (sq2 * sq3), -r / (sq2 * sq3), -r *  sq2 / sq3 );
01257 
01258     make_polygon(  0, 19,  4 );
01259     make_polygon(  1,  7,  8 );
01260     make_polygon(  2, 11, 12 );
01261     make_polygon(  3, 15, 16 );
01262     make_polygon( 20,  5, 18 );
01263     make_polygon( 21,  9,  6 );
01264     make_polygon( 22, 13, 10 );
01265     make_polygon( 23, 17, 14 );
01266 
01267     make_polygon(  0,  1,  2,  3 );
01268     make_polygon(  4,  5,  6,  7 );
01269     make_polygon(  8,  9, 10, 11 );
01270     make_polygon( 12, 13, 14, 15 );
01271     make_polygon( 16, 17, 18, 19 );
01272     make_polygon( 20, 21, 22, 23 );
01273 
01274     make_polygon(  0,  4,  7,  1 );
01275     make_polygon(  1,  8, 11,  2 );
01276     make_polygon(  2, 12, 15,  3 );
01277     make_polygon(  3, 16, 19,  0 );
01278     make_polygon( 20,  5,  6, 21 );
01279     make_polygon( 21,  9, 10, 22 );
01280     make_polygon( 22, 13, 14, 23 );
01281     make_polygon( 23, 17, 18, 20 );
01282 
01283     build_mesh_from_geometry();
01284 }
01285 
01286 #endif
01287 truncated_octahedron::truncated_octahedron(double r)
01288 {
01289     push_point(           0,      r / sq5,  r * 2 / sq5);
01290     push_point(     r / sq5,            0,  r * 2 / sq5);
01291     push_point(           0,     -r / sq5,  r * 2 / sq5);
01292     push_point(    -r / sq5,            0,  r * 2 / sq5);
01293     push_point(           0,  r * 2 / sq5,      r / sq5);
01294     push_point(    -r / sq5,  r * 2 / sq5,            0);
01295     push_point(           0,  r * 2 / sq5,     -r / sq5);
01296     push_point(     r / sq5,  r * 2 / sq5,            0);
01297     push_point( r * 2 / sq5,            0,      r / sq5);
01298     push_point( r * 2 / sq5,      r / sq5,            0);
01299     push_point( r * 2 / sq5,            0,     -r / sq5);
01300     push_point( r * 2 / sq5,     -r / sq5,            0);
01301     push_point(           0, -r * 2 / sq5,      r / sq5);
01302     push_point(     r / sq5, -r * 2 / sq5,            0);
01303     push_point(           0, -r * 2 / sq5,     -r / sq5);
01304     push_point(    -r / sq5, -r * 2 / sq5,            0);
01305     push_point(-r * 2 / sq5,            0,      r / sq5);
01306     push_point(-r * 2 / sq5,     -r / sq5,            0);
01307     push_point(-r * 2 / sq5,            0,     -r / sq5);
01308     push_point(-r * 2 / sq5,      r / sq5,            0);
01309     push_point(           0,      r / sq5, -r * 2 / sq5);
01310     push_point(     r / sq5,            0, -r * 2 / sq5);
01311     push_point(           0,     -r / sq5, -r * 2 / sq5);
01312     push_point(    -r / sq5,            0, -r * 2 / sq5);
01313 
01314     make_polygon(  0,  1,  2,  3 );
01315     make_polygon(  4,  5,  6,  7 );
01316     make_polygon(  8,  9, 10, 11 );
01317     make_polygon( 12, 13, 14, 15 );
01318     make_polygon( 16, 17, 18, 19 );
01319     make_polygon( 20, 21, 22, 23 );
01320 
01321     make_polygon(  0,  4,  7,  9,  8,  1 );
01322     make_polygon(  1,  8, 11, 13, 12,  2 );
01323     make_polygon(  2, 12, 15, 17, 16,  3 );
01324     make_polygon(  3, 16, 19,  5,  4,  0 );
01325     make_polygon( 20,  6,  7,  9, 10, 21 );
01326     make_polygon( 21, 10, 11, 13, 14, 22 );
01327     make_polygon( 22, 14, 15, 17, 18, 23 );
01328     make_polygon( 23, 18, 19,  5,  6, 20 );
01329 
01330     build_mesh_from_geometry();
01331 }
01332 
01333 truncated_icosahedron::truncated_icosahedron()
01334 {
01335     push_point( 0.0,                  0.0,                 0.0 );
01336     push_point(-0.16245984811645317, -2.118033988749895,   1.2759762125280598 );
01337     push_point(-0.16245984811645317,  2.118033988749895,   1.2759762125280598);
01338     push_point( 0.16245984811645317, -2.118033988749895,  -1.27597621252806 );
01339     push_point( 0.16245984811645317,  2.118033988749895,  -1.27597621252806 );
01340     push_point(-0.2628655560595668,  -0.8090169943749473, -2.327438436766327 );
01341     push_point(-0.2628655560595668,  -2.4270509831248424, -0.42532540417601994 );
01342     push_point(-0.2628655560595668,   0.8090169943749475, -2.327438436766327 );
01343     push_point(-0.2628655560595668,   2.4270509831248424, -0.42532540417601994 );
01344     push_point( 0.2628655560595668,  -0.8090169943749473,  2.327438436766327 );
01345     push_point( 0.2628655560595668,  -2.4270509831248424,  0.42532540417601994 );
01346     push_point( 0.2628655560595668,   0.8090169943749475,  2.327438436766327);
01347     push_point( 0.2628655560595668,   2.4270509831248424,  0.42532540417601994 );
01348     push_point( 0.6881909602355868,  -0.5,                -2.327438436766327 );
01349     push_point( 0.6881909602355868,   0.5,                -2.327438436766327 );
01350     push_point( 1.2139220723547204,  -2.118033988749895,   0.42532540417601994 );
01351     push_point( 1.2139220723547204,   2.118033988749895,   0.42532540417601994 );
01352     push_point(-2.0645728807067605,  -0.5,                 1.2759762125280598 );
01353     push_point(-2.0645728807067605,   0.5,                 1.2759762125280598 );
01354     push_point(-1.3763819204711736,  -1,                   1.8017073246471935 );
01355     push_point(-1.3763819204711736,   1,                   1.8017073246471935 );
01356     push_point(-1.3763819204711736,  -1.6180339887498947, -1.27597621252806 );
01357     push_point(-1.3763819204711736,   1.618033988749895,  -1.27597621252806 );
01358     push_point(-0.6881909602355868,  -0.5,                 2.327438436766327 );
01359     push_point(-0.6881909602355868,   0.5,                 2.327438436766327 );
01360     push_point( 1.3763819204711736,  -1,                  -1.8017073246471933 );
01361     push_point( 1.3763819204711736,   1,                  -1.8017073246471933 );
01362     push_point( 1.3763819204711736,  -1.6180339887498947,  1.2759762125280598 );
01363     push_point( 1.3763819204711736,   1.618033988749895,   1.2759762125280598);
01364     push_point(-1.7013016167040798,   0,                  -1.8017073246471933 );
01365     push_point( 1.7013016167040798,   0,                   1.8017073246471935 );
01366     push_point(-1.2139220723547204,  -2.118033988749895,  -0.42532540417601994 );
01367     push_point(-1.2139220723547204,   2.118033988749895,  -0.42532540417601994 );
01368     push_point(-1.9641671727636467,  -0.8090169943749473, -1.27597621252806 );
01369     push_point(-1.9641671727636467,   0.8090169943749475, -1.27597621252806 );
01370     push_point( 2.0645728807067605,  -0.5,                -1.27597621252806 );
01371     push_point( 2.0645728807067605,   0.5,                -1.27597621252806 );
01372     push_point( 2.2270327288232132,  -1,                  -0.42532540417601994 );
01373     push_point( 2.2270327288232132,   1,                  -0.42532540417601994 );
01374     push_point( 2.3894925769396664,  -0.5,                 0.42532540417601994 );
01375     push_point( 2.3894925769396664,   0.5,                 0.42532540417601994 );
01376     push_point(-1.1135163644116066,  -1.8090169943749475,  1.2759762125280598 );
01377     push_point(-1.1135163644116066,   1.8090169943749475,  1.2759762125280598 );
01378     push_point( 1.1135163644116066,  -1.8090169943749475, -1.27597621252806 );
01379     push_point( 1.1135163644116066,   1.8090169943749475, -1.27597621252806 );
01380     push_point(-2.3894925769396664,  -0.5,                -0.42532540417601994 );
01381     push_point(-2.3894925769396664,   0.5,                -0.42532540417601994 );
01382     push_point(-1.6392474765307403,  -1.8090169943749475,  0.42532540417601994 );
01383     push_point(-1.6392474765307403,   1.8090169943749475,  0.42532540417601994 );
01384     push_point( 1.6392474765307403,  -1.8090169943749475, -0.42532540417601994);
01385     push_point( 1.6392474765307403,   1.8090169943749475, -0.42532540417601994 );
01386     push_point( 1.9641671727636467,  -0.8090169943749473,  1.2759762125280598);
01387     push_point( 1.9641671727636467,   0.8090169943749475,  1.2759762125280598);
01388     push_point( 0.85065080835204,     0,                   2.327438436766327 );
01389     push_point(-2.2270327288232132,  -1,                   0.42532540417601994 );
01390     push_point(-2.2270327288232132,   1,                   0.42532540417601994 );
01391     push_point(-0.85065080835204,     0,                  -2.327438436766327 );
01392     push_point(-0.5257311121191336,  -1.6180339887498947, -1.8017073246471933 );
01393     push_point(-0.5257311121191336,   1.618033988749895,  -1.8017073246471933);
01394     push_point( 0.5257311121191336,  -1.6180339887498947,  1.8017073246471935 );
01395     push_point( 0.5257311121191336,   1.618033988749895,   1.8017073246471935);
01396 
01397     make_polygon( 53, 11, 24, 23,  9 );
01398     make_polygon( 51, 39, 40, 52, 30 );
01399     make_polygon( 60, 28, 16, 12,  2 );
01400     make_polygon( 20, 42, 48, 55, 18 );
01401     make_polygon( 19, 17, 54, 47, 41 );
01402     make_polygon(  1, 10, 15, 27, 59 );
01403     make_polygon( 36, 26, 44, 50, 38 );
01404     make_polygon(  4, 58, 22, 32,  8 );
01405     make_polygon( 34, 29, 33, 45, 46 );
01406     make_polygon( 21, 57,  3,  6, 31 );
01407     make_polygon( 37, 49, 43, 25, 35 );
01408     make_polygon( 13,  5, 56,  7, 14 );
01409     make_polygon(  9, 59, 27, 51, 30, 53 );
01410     make_polygon( 53, 30, 52, 28, 60, 11 );
01411     make_polygon( 11, 60,  2, 42, 20, 24 );
01412     make_polygon( 24, 20, 18, 17, 19, 23 );
01413     make_polygon( 23, 19, 41,  1, 59,  9 );
01414     make_polygon( 13, 25, 43,  3, 57,  5 );
01415     make_polygon(  5, 57, 21, 33, 29, 56 );
01416     make_polygon( 56, 29, 34, 22, 58,  7 );
01417     make_polygon(  7, 58,  4, 44, 26, 14 );
01418     make_polygon( 14, 26, 36, 35, 25, 13 );
01419     make_polygon( 40, 38, 50, 16, 28, 52 );
01420     make_polygon( 16, 50, 44,  4,  8, 12 );
01421     make_polygon( 12,  8, 32, 48, 42,  2 );
01422     make_polygon( 48, 32, 22, 34, 46, 55 );
01423     make_polygon( 55, 46, 45, 54, 17, 18 );
01424     make_polygon( 54, 45, 33, 21, 31, 47 );
01425     make_polygon( 47, 31,  6, 10,  1, 41 );
01426     make_polygon( 10,  6,  3, 43, 49, 15 );
01427     make_polygon( 15, 49, 37, 39, 51, 27 );
01428     make_polygon( 39, 37, 35, 36, 38, 40 );
01429 
01430     build_mesh_from_geometry();
01431 }
01432 
01433 great_rhombicosidodecahedron::great_rhombicosidodecahedron()
01434 {
01435     push_point(0.0, 0.0, 0.0 );
01436     push_point(-1, -1.3090169943749475, -3.4270509831248424 );
01437     push_point(-1, -1.3090169943749475, 3.4270509831248424 );
01438     push_point(-1, 1.3090169943749475, -3.4270509831248424 );
01439     push_point(-1, 1.3090169943749475, 3.4270509831248424 );
01440     push_point(-0.5, -0.5, -3.73606797749979 );
01441     push_point(-0.5, -0.5, 3.73606797749979 );
01442     push_point(-0.5, 0.5, -3.73606797749979 );
01443     push_point(-0.5, 0.5, 3.73606797749979 );
01444     push_point(-0.5, -3.73606797749979, -0.5 );
01445     push_point(-0.5, -3.73606797749979,  0.5 );
01446     push_point(-0.5, -2.118033988749895, -3.118033988749895 );
01447     push_point(-0.5, -2.118033988749895, 3.118033988749895 );
01448     push_point(-0.5, 3.73606797749979, -0.5 );
01449     push_point(-0.5, 3.73606797749979, 0.5 );
01450     push_point(-0.5, 2.118033988749895, -3.118033988749895 );
01451     push_point(-0.5, 2.118033988749895, 3.118033988749895 );
01452     push_point(0.5, -0.5, -3.73606797749979 );
01453     push_point(0.5, -0.5, 3.73606797749979 );
01454     push_point(0.5, 0.5, -3.73606797749979 );
01455     push_point(0.5, 0.5, 3.73606797749979 );
01456     push_point(0.5, -3.73606797749979, -0.5 );
01457     push_point(0.5, -3.73606797749979, 0.5 );
01458     push_point(0.5, -2.118033988749895, -3.118033988749895 );
01459     push_point(0.5, -2.118033988749895, 3.118033988749895 );
01460     push_point(0.5, 3.73606797749979, -0.5 );
01461     push_point(0.5, 3.73606797749979, 0.5 );
01462     push_point(0.5, 2.118033988749895, -3.118033988749895 );
01463     push_point(0.5, 2.118033988749895, 3.118033988749895 );
01464     push_point(1, -1.3090169943749475, -3.4270509831248424 );
01465     push_point(1, -1.3090169943749475, 3.4270509831248424 );
01466     push_point(1, 1.3090169943749475, -3.4270509831248424 );
01467     push_point(1, 1.3090169943749475, 3.4270509831248424 );
01468     push_point(-3.4270509831248424, -1, -1.3090169943749475 );
01469     push_point(-3.4270509831248424, -1, 1.3090169943749475 );
01470     push_point(-3.4270509831248424, 1, -1.3090169943749475 );
01471     push_point(-3.4270509831248424, 1, 1.3090169943749475 );
01472     push_point(-2.9270509831248424, -1.8090169943749475, -1.618033988749895 );
01473     push_point(-2.9270509831248424, -1.8090169943749475, 1.618033988749895 );
01474     push_point(-2.9270509831248424, 1.8090169943749475, -1.618033988749895 );
01475     push_point(-2.9270509831248424, 1.8090169943749475, 1.618033988749895 );
01476     push_point(-1.8090169943749475, -1.618033988749895, -2.9270509831248424 );
01477     push_point(-1.8090169943749475, -1.618033988749895, 2.9270509831248424 );
01478     push_point(-1.8090169943749475, 1.618033988749895, -2.9270509831248424 );
01479     push_point(-1.8090169943749475, 1.618033988749895, 2.9270509831248424 );
01480     push_point(-1.3090169943749475, -3.4270509831248424, -1 );
01481     push_point(-1.3090169943749475, -3.4270509831248424, 1 );
01482     push_point(-1.3090169943749475, -2.4270509831248424, -2.618033988749895 );
01483     push_point(-1.3090169943749475, -2.4270509831248424, 2.618033988749895 );
01484     push_point(-1.3090169943749475, 2.4270509831248424, -2.618033988749895 );
01485     push_point(-1.3090169943749475, 2.4270509831248424, 2.618033988749895 );
01486     push_point(-1.3090169943749475, 3.4270509831248424, -1 );
01487     push_point(-1.3090169943749475, 3.4270509831248424, 1 );
01488     push_point(-2.618033988749895, -1.3090169943749475, -2.4270509831248424 );
01489     push_point(-2.618033988749895, -1.3090169943749475, 2.4270509831248424 );
01490     push_point(-2.618033988749895, 1.3090169943749475, -2.4270509831248424 );
01491     push_point(-2.618033988749895, 1.3090169943749475, 2.4270509831248424 );
01492     push_point(-3.73606797749979, -0.5, -0.5 );
01493     push_point(-3.73606797749979, -0.5, 0.5 );
01494     push_point(-3.73606797749979, 0.5, -0.5 );
01495     push_point(-3.73606797749979, 0.5, 0.5 );
01496     push_point(-1.618033988749895, -2.9270509831248424, -1.8090169943749475 );
01497     push_point(-1.618033988749895, -2.9270509831248424, 1.8090169943749475 );
01498     push_point(-1.618033988749895, 2.9270509831248424, -1.8090169943749475 );
01499     push_point(-1.618033988749895, 2.9270509831248424, 1.8090169943749475 );
01500     push_point(-3.118033988749895, -0.5, -2.118033988749895 );
01501     push_point(-3.118033988749895, -0.5, 2.118033988749895 );
01502     push_point(-3.118033988749895, 0.5, -2.118033988749895 );
01503     push_point(-3.118033988749895, 0.5, 2.118033988749895 );
01504     push_point(-2.118033988749895, -3.118033988749895, -0.5 );
01505     push_point(-2.118033988749895, -3.118033988749895, 0.5 );
01506     push_point(-2.118033988749895, 3.118033988749895, -0.5 );
01507     push_point(-2.118033988749895, 3.118033988749895, 0.5 );
01508     push_point(-2.4270509831248424, -2.618033988749895, -1.3090169943749475 );
01509     push_point(-2.4270509831248424, -2.618033988749895, 1.3090169943749475 );
01510     push_point(-2.4270509831248424, 2.618033988749895, -1.3090169943749475 );
01511     push_point(-2.4270509831248424, 2.618033988749895, 1.3090169943749475 );
01512     push_point( 1.618033988749895, -2.9270509831248424, -1.8090169943749475);
01513     push_point( 1.618033988749895, -2.9270509831248424, 1.8090169943749475);
01514     push_point( 1.618033988749895, 2.9270509831248424, -1.8090169943749475);
01515     push_point( 1.618033988749895, 2.9270509831248424, 1.8090169943749475 );
01516     push_point( 2.4270509831248424, -2.618033988749895, -1.3090169943749475 );
01517     push_point( 2.4270509831248424, -2.618033988749895, 1.3090169943749475 );
01518     push_point( 2.4270509831248424, 2.618033988749895, -1.3090169943749475 );
01519     push_point( 2.4270509831248424, 2.618033988749895, 1.3090169943749475 );
01520     push_point( 3.73606797749979, -0.5, -0.5 );
01521     push_point( 3.73606797749979, -0.5, 0.5 );
01522     push_point( 3.73606797749979, 0.5, -0.5 );
01523     push_point( 3.73606797749979, 0.5, 0.5 );
01524     push_point( 2.118033988749895, -3.118033988749895, -0.5 );
01525     push_point( 2.118033988749895, -3.118033988749895, 0.5 );
01526     push_point( 2.118033988749895, 3.118033988749895, -0.5 );
01527     push_point( 2.118033988749895, 3.118033988749895, 0.5 );
01528     push_point( 1.3090169943749475, -3.4270509831248424, -1 );
01529     push_point( 1.3090169943749475, -3.4270509831248424, 1 );
01530     push_point( 1.3090169943749475, -2.4270509831248424, -2.618033988749895 );
01531     push_point( 1.3090169943749475, -2.4270509831248424, 2.618033988749895 );
01532     push_point( 1.3090169943749475, 2.4270509831248424, -2.618033988749895 );
01533     push_point( 1.3090169943749475, 2.4270509831248424, 2.618033988749895 );
01534     push_point( 1.3090169943749475, 3.4270509831248424, -1 );
01535     push_point( 1.3090169943749475, 3.4270509831248424, 1 );
01536     push_point( 2.618033988749895, -1.3090169943749475, -2.4270509831248424);
01537     push_point( 2.618033988749895, -1.3090169943749475, 2.4270509831248424 );
01538     push_point( 2.618033988749895, 1.3090169943749475, -2.4270509831248424);
01539     push_point( 2.618033988749895, 1.3090169943749475, 2.4270509831248424 );
01540     push_point( 3.118033988749895, -0.5, -2.118033988749895 );
01541     push_point( 3.118033988749895, -0.5, 2.118033988749895 );
01542     push_point( 3.118033988749895, 0.5, -2.118033988749895 );
01543     push_point( 3.118033988749895, 0.5,  2.118033988749895 );
01544     push_point( 1.8090169943749475, -1.618033988749895, -2.9270509831248424 );
01545     push_point( 1.8090169943749475, -1.618033988749895, 2.9270509831248424 );
01546     push_point( 1.8090169943749475, 1.618033988749895, -2.9270509831248424 );
01547     push_point( 1.8090169943749475, 1.618033988749895, 2.9270509831248424 );
01548     push_point( 2.9270509831248424, -1.8090169943749475, -1.618033988749895 );
01549     push_point( 2.9270509831248424, -1.8090169943749475, 1.618033988749895 );
01550     push_point( 2.9270509831248424, 1.8090169943749475, -1.618033988749895 );
01551     push_point( 2.9270509831248424, 1.8090169943749475, 1.618033988749895 );
01552     push_point( 3.4270509831248424, -1, -1.3090169943749475 );
01553     push_point( 3.4270509831248424, -1, 1.3090169943749475 );
01554     push_point( 3.4270509831248424, 1, -1.3090169943749475 );
01555     push_point( 3.4270509831248424, 1, 1.3090169943749475);
01556 
01557     make_polygon(   2,   6,   8,   4,  44,  56,  68,  66,  54,  42 );
01558     make_polygon( 109,  29,  17,  19,  31, 111, 103, 107, 105, 101 );
01559     make_polygon(  58,  57,  33,  37,  73,  69,  70,  74,  38,  34 );
01560     make_polygon(  84, 116, 120,  88,  87, 119, 115,  83,  91,  92 );
01561     make_polygon(  90,  89,  81, 113, 117,  85,  86, 118, 114,  82 );
01562     make_polygon(  36,  40,  76,  72,  71,  75,  39,  35,  59,  60 );
01563     make_polygon(  67,  55,  43,   3,   7,   5,   1,  41,  53,  65 );
01564     make_polygon(  18,  30, 110, 102, 106, 108, 104, 112,  32,  20 );
01565     make_polygon(  61,  47,  11,  23,  95,  77,  93,  21,   9,  45 );
01566     make_polygon(  50,  16,  28,  98,  80, 100,  26,  14,  52,  64 );
01567     make_polygon(  63,  51,  13,  25,  99,  79,  97,  27,  15,  49 );
01568     make_polygon(  46,  10,  22,  94,  78,  96,  24,  12,  48,  62 );
01569     make_polygon(  24,  30,  18,   6,   2,  12 );
01570     make_polygon(   7,   3,  15,  27,  31,  19 );
01571     make_polygon(   5,  17,  29,  23,  11,   1 );
01572     make_polygon(   4,   8,  20,  32,  28,  16 );
01573     make_polygon(  79,  83, 115, 103, 111,  97 );
01574     make_polygon(  38,  74,  62,  48,  42,  54 );
01575     make_polygon(  53,  41,  47,  61,  73,  37 );
01576     make_polygon(  98, 112, 104, 116,  84,  80 );
01577     make_polygon(  69,  45,   9,  10,  46,  70 );
01578     make_polygon(  26, 100,  92,  91,  99,  25 );
01579     make_polygon(  82, 114, 102, 110,  96,  78 );
01580     make_polygon(  55,  39,  75,  63,  49,  43 );
01581     make_polygon(  44,  50,  64,  76,  40,  56 );
01582     make_polygon(  77,  95, 109, 101, 113,  81 );
01583     make_polygon(  52,  14,  13,  51,  71,  72 );
01584     make_polygon(  22,  21,  93,  89,  90,  94 );
01585     make_polygon(  59,  35,  67,  65,  33,  57 );
01586     make_polygon( 106, 118,  86,  88, 120, 108 );
01587     make_polygon(  34,  66,  68,  36,  60,  58 );
01588     make_polygon( 105, 107, 119,  87,  85, 117 );
01589     make_polygon(   4,  16,  50,  44 );
01590     make_polygon(  23,  29, 109,  95 );
01591     make_polygon(  96, 110,  30,  24 );
01592     make_polygon(  43,  49,  15,   3 );
01593     make_polygon(   1,  11,  47,  41 );
01594     make_polygon(  28,  32, 112,  98 );
01595     make_polygon(  97, 111,  31,  27 );
01596     make_polygon(  42,  48,  12,   2 );
01597     make_polygon( 115, 119, 107, 103 );
01598     make_polygon(  34,  38,  54,  66 );
01599     make_polygon(  71,  51,  63,  75 );
01600     make_polygon(  94,  90,  82,  78 );
01601     make_polygon( 114, 118, 106, 102 );
01602     make_polygon(  35,  39,  55,  67 );
01603     make_polygon(  70,  46,  62,  74 );
01604     make_polygon(  99,  91,  83,  79 );
01605     make_polygon(  65,  53,  37,  33 );
01606     make_polygon( 104, 108, 120, 116 );
01607     make_polygon(  77,  81,  89,  93 );
01608     make_polygon(  76,  64,  52,  72 );
01609     make_polygon(  68,  56,  40,  36 );
01610     make_polygon( 101, 105, 117, 113 );
01611     make_polygon(  80,  84,  92, 100 );
01612     make_polygon(  73,  61,  45,  69 );
01613     make_polygon(   7,  19,  17,   5 );
01614     make_polygon(   6,  18,  20,   8 );
01615     make_polygon(  14,  26,  25,  13 );
01616     make_polygon(   9,  21,  22,  10 );
01617     make_polygon(  58,  60,  59,  57 );
01618     make_polygon(  85,  87,  88,  86 );
01619 
01620     build_mesh_from_geometry();
01621 }
01622 
01623 truncated_dodecahedron::truncated_dodecahedron()
01624 {
01625     push_point(0.0, 0.0, 0.0 );
01626     push_point(0, -1.618033988749895, 2.48989828488278);
01627     push_point(0, -1.618033988749895, -2.48989828488278);
01628     push_point(0, 1.618033988749895, 2.48989828488278);
01629     push_point(0, 1.618033988749895, -2.48989828488278);
01630     push_point(0.42532540417601994, -2.9270509831248424, 0.2628655560595668);
01631     push_point(0.42532540417601994, 2.9270509831248424, 0.2628655560595668);
01632     push_point(0.6881909602355868, -2.118033988749895, 1.9641671727636467);
01633     push_point(0.6881909602355868, 2.118033988749895, 1.9641671727636467);
01634     push_point(-2.752763840942347, 0, -1.1135163644116068);
01635     push_point(-2.0645728807067605, -2.118033988749895, 0.2628655560595668);
01636     push_point(-2.0645728807067605, 2.118033988749895, 0.2628655560595668);
01637     push_point(-1.3763819204711736, -2.618033988749895, -0.2628655560595668);
01638     push_point(-1.3763819204711736, 2.618033988749895, -0.2628655560595668);
01639     push_point(-0.6881909602355868, -2.118033988749895, -1.9641671727636467);
01640     push_point(-0.6881909602355868, 2.118033988749895, -1.9641671727636467);
01641     push_point(1.3763819204711736, -2.618033988749895, 0.2628655560595668);
01642     push_point(1.3763819204711736, 2.618033988749895, 0.2628655560595668);
01643     push_point(2.752763840942347, 0, 1.1135163644116066);
01644     push_point(1.8017073246471935, -1.3090169943749475, -1.9641671727636467);
01645     push_point(1.8017073246471935, 1.3090169943749475, -1.9641671727636467);
01646     push_point(2.0645728807067605, -2.118033988749895, -0.2628655560595668);
01647     push_point(2.0645728807067605, 2.118033988749895, -0.2628655560595668);
01648     push_point(2.2270327288232132, 0, 1.9641671727636467);
01649     push_point(2.2270327288232132, -1.618033988749895, -1.1135163644116068);
01650     push_point(2.2270327288232132, 1.618033988749895, -1.1135163644116068);
01651     push_point(-2.6523581329992334, -1.3090169943749475, 0.2628655560595668);
01652     push_point(-2.6523581329992334, 1.3090169943749475, 0.2628655560595668);
01653     push_point(2.6523581329992334, -1.3090169943749475, -0.2628655560595668);
01654     push_point(2.6523581329992334, 1.3090169943749475, -0.2628655560595668);
01655     push_point(2.9152236890588, -0.5, 0.2628655560595668);
01656     push_point(2.9152236890588, 0.5, 0.2628655560595668);
01657     push_point(-2.9152236890588, -0.5, -0.2628655560595668);
01658     push_point(-2.9152236890588, 0.5, -0.2628655560595668);
01659     push_point(0.9510565162951535, -1.3090169943749475, 2.48989828488278);
01660     push_point(0.9510565162951535, -1.3090169943749475, -2.48989828488278);
01661     push_point(0.9510565162951535, 1.3090169943749475, 2.48989828488278);
01662     push_point(0.9510565162951535, 1.3090169943749475, -2.48989828488278);
01663     push_point(0.85065080835204, -2.618033988749895, 1.1135163644116066);
01664     push_point(0.85065080835204, 2.618033988749895, 1.1135163644116066);
01665     push_point(-0.9510565162951535, -1.3090169943749475, 2.48989828488278);
01666     push_point(-0.9510565162951535, -1.3090169943749475, -2.48989828488278);
01667     push_point(-0.9510565162951535, 1.3090169943749475, 2.48989828488278);
01668     push_point(-0.9510565162951535, 1.3090169943749475, -2.48989828488278);
01669     push_point(-1.5388417685876268, -0.5, 2.48989828488278);
01670     push_point(-1.5388417685876268, -0.5, -2.48989828488278);
01671     push_point(-1.5388417685876268, 0.5, 2.48989828488278);
01672     push_point(-1.5388417685876268, 0.5, -2.48989828488278);
01673     push_point(1.5388417685876268, -0.5, 2.48989828488278);
01674     push_point(1.5388417685876268, -0.5, -2.48989828488278);
01675     push_point(1.5388417685876268, 0.5, 2.48989828488278);
01676     push_point(1.5388417685876268, 0.5, -2.48989828488278);
01677     push_point(-2.2270327288232132, 0, -1.9641671727636467);
01678     push_point(-2.2270327288232132, -1.618033988749895, 1.1135163644116066);
01679     push_point(-2.2270327288232132, 1.618033988749895, 1.1135163644116066);
01680     push_point(-0.85065080835204, -2.618033988749895, -1.1135163644116068);
01681     push_point(-0.85065080835204, 2.618033988749895, -1.1135163644116068);
01682     push_point(-1.8017073246471933, -1.3090169943749475, 1.9641671727636467);
01683     push_point(-1.8017073246471933, 1.3090169943749475, 1.9641671727636467);
01684     push_point(-0.42532540417601994, -2.9270509831248424, -0.2628655560595668);
01685     push_point(-0.42532540417601994, 2.9270509831248424, -0.2628655560595668);
01686 
01687     make_polygon(  3, 42, 46, 44, 40,  1, 34, 48, 50, 36);
01688     make_polygon( 47, 43,  4, 37, 51, 49, 35,  2, 41, 45);
01689     make_polygon(  2, 35, 19, 24, 21, 16,  5, 59, 55, 14);
01690     make_polygon( 49, 51, 20, 25, 29, 31, 30, 28, 24, 19);
01691     make_polygon( 37,  4, 15, 56, 60,  6, 17, 22, 25, 20);
01692     make_polygon( 43, 47, 52,  9, 33, 27, 11, 13, 56, 15);
01693     make_polygon( 45, 41, 14, 55, 12, 10, 26, 32,  9, 52);
01694     make_polygon(  6, 60, 13, 11, 54, 58, 42,  3,  8, 39);
01695     make_polygon( 27, 33, 32, 26, 53, 57, 44, 46, 58, 54);
01696     make_polygon( 10, 12, 59,  5, 38,  7,  1, 40, 57, 53);
01697     make_polygon( 16, 21, 28, 30, 18, 23, 48, 34,  7, 38);
01698     make_polygon( 31, 29, 22, 17, 39,  8, 36, 50, 23, 18);
01699     make_polygon(  9, 32, 33);
01700     make_polygon( 18, 30, 31);
01701     make_polygon( 47, 45, 52);
01702     make_polygon( 50, 48, 23);
01703     make_polygon( 10, 53, 26);
01704     make_polygon( 27, 54, 11);
01705     make_polygon( 21, 24, 28);
01706     make_polygon( 29, 25, 22);
01707     make_polygon( 40, 44, 57);
01708     make_polygon( 58, 46, 42);
01709     make_polygon( 35, 49, 19);
01710     make_polygon( 20, 51, 37);
01711     make_polygon( 12, 55, 59);
01712     make_polygon( 60, 56, 13);
01713     make_polygon( 41,  2, 14);
01714     make_polygon( 15,  4, 43);
01715     make_polygon( 34,  1,  7);
01716     make_polygon(  8,  3, 36);
01717     make_polygon( 38,  5, 16);
01718     make_polygon( 17,  6, 39);
01719 
01720     build_mesh_from_geometry();
01721 }
01722 
01723 johnson_solid::johnson_solid(int number)
01724 {
01725     if(number != 83)
01726     {
01727         throw false;
01728     }
01729     push_point(0.622866913219, 0.618689929055, 0.268875295373);
01730     push_point(0.632830203313, 0.667979230789, -0.15223981211);
01731     push_point(0.260097696343, 0.86976646536, -0.137440272303);
01732     push_point(0.25013440625, 0.820477163625, 0.283674835181);
01733     push_point(-0.108878198249, 0.894110390313, 0.0702392854136);
01734     push_point(0.051935606844, 0.787120294271, -0.497585786041);
01735     push_point(-0.317040287749, 0.811464219225, -0.289906228324);
01736     push_point(0.655029471832, 0.46062169024, -0.521531944467);
01737     push_point(0.296016867333, 0.534254916928, -0.734967494234);
01738     push_point(-0.87205832873, 0.228232662749, -0.239314442373);
01739     push_point(-0.669974565739, 0.597988139875, -0.191255353363);
01740     push_point(0.32197274823, 0.149454066762, -0.911379608681);
01741     push_point(0.119888985239, -0.220301410364, -0.959438697691);
01742     push_point(-0.233045292752, -0.433777489714, -0.86078782273);
01743     push_point(-0.602021187345, -0.409433564761, -0.653108265014);
01744     push_point(-0.846102447834, -0.156568187418, -0.415726556821);
01745     push_point(-0.33316122976, 0.731712453736, 0.39147232876);
01746     push_point(0.0258513747388, 0.658079227048, 0.604907878527);
01747     push_point(-0.327082903252, 0.444603147699, 0.703558753488);
01748     push_point(-0.679937855833, 0.54869883814, 0.22985975412);
01749     push_point(-0.673859529325, 0.261589532103, 0.541946178848);
01750     push_point(-0.882021618824, 0.178943361014, 0.18180066511);
01751     push_point(-0.862223389845, -0.236319952906, 0.265652000264);
01752     push_point(-0.654061300346, -0.153673781818, 0.625797514001);
01753     push_point(-0.840024121326, -0.443677493455, -0.103640132093);
01754     push_point(-0.595942860836, -0.696542870798, -0.341021840286);
01755     push_point(-0.092964932856, 0.142448468621, 0.887292152778);
01756     push_point(0.259969345135, 0.35592454797, 0.788641277817);
01757     push_point(0.279767574113, -0.0593387659499, 0.872492612971);
01758     push_point(-0.295048695847, -0.227307008505, 0.839233063768);
01759     push_point(0.0776838111221, -0.429094243076, 0.824433523961);
01760     push_point(0.343964340131, -0.889317160968, 0.217759683411);
01761     push_point(0.321765071612, -0.681959620419, 0.587051815768);
01762     push_point(-0.223210353867, -0.898330105369, -0.355821380093);
01763     push_point(0.135802250632, -0.971963332057, -0.142385830326);
01764     push_point(0.648743468706, -0.0836826909031, 0.664813055254);
01765     push_point(0.628945239727, 0.331580623017, 0.580961720101);
01766     push_point(0.674699349602, -0.46848354107, 0.488400940807);
01767     push_point(0.696898618122, -0.675841081619, 0.119108808451);
01768     push_point(0.706861908215, -0.626551779884, -0.302006299033);
01769     push_point(0.700783581707, -0.339442473847, -0.614092723761);
01770     push_point(0.680985352729, 0.0758208400738, -0.697944058914);
01771     push_point(0.360085282143, -0.80956539548, -0.463618873673);
01772     push_point(0.00107267764377, -0.735932168792, -0.67705442344);
01773     push_point(0.354006955634, -0.522456089442, -0.775705298401);
01774 
01775     make_polygon(  9, 10,  6,  5,  8, 11, 12, 13, 14, 15);
01776     make_polygon( 31, 32, 30, 29, 23, 22, 24, 25, 33, 34);
01777     make_polygon( 36, 35, 37, 38, 39, 40, 41,  7,  1,  0);
01778     make_polygon(  1,  7,  8,  5,  2);
01779     make_polygon(  4,  6, 10, 19, 16);
01780     make_polygon(  9, 15, 24, 22, 21);
01781     make_polygon( 18, 20, 23, 29, 26);
01782     make_polygon( 28, 30, 32, 37, 35);
01783     make_polygon( 31, 34, 42, 39, 38);
01784     make_polygon( 40, 44, 12, 11, 41);
01785     make_polygon(  0,  3, 17, 27, 36);
01786     make_polygon( 43, 33, 25, 14, 13);
01787     make_polygon(  0,  1,  2,  3);
01788     make_polygon(  2,  5,  6,  4);
01789     make_polygon(  3,  4, 16, 17);
01790     make_polygon( 16, 19, 20, 18);
01791     make_polygon( 20, 21, 22, 23);
01792     make_polygon( 10,  9, 21, 19);
01793     make_polygon( 15, 14, 25, 24);
01794     make_polygon( 17, 18, 26, 27);
01795     make_polygon( 26, 29, 30, 28);
01796     make_polygon( 27, 28, 35, 36);
01797     make_polygon( 32, 31, 38, 37);
01798     make_polygon( 34, 33, 43, 42);
01799     make_polygon(  7, 41, 11,  8);
01800     make_polygon( 39, 42, 44, 40);
01801     make_polygon( 44, 43, 13, 12);
01802     make_polygon(  3,  2,  4);
01803     make_polygon( 17, 16, 18);
01804     make_polygon( 19, 21, 20);
01805     make_polygon( 27, 26, 28);
01806     make_polygon( 42, 43, 44);
01807 
01808     build_mesh_from_geometry();
01809 }
01810 
01811 grid::grid(float cell_width, int positive_cell_count)
01812 {
01813     /*    2   9  11  13   3    0.. 3  corners              */ 
01814     /*                         2.. 7  min_x...max_x lines  */ 
01815     /*    6   .   .   .   7    8..13  min_z..,max_z lines  */ 
01816     /*                                                     */ 
01817     /*    4   .   x   .   5    positive_cell_count = 2     */ 
01818     /*                                                     */ 
01819     /*    2   .   .   .   3                                */ 
01820     /*                                                     */ 
01821     /*    0   8  10  12   1                                */ 
01822 
01823     float extreme = (float)(positive_cell_count) * cell_width;
01824     int index = 0;
01825 
01826     /*  Corner vertices  */ 
01827     {
01828         push_point(-extreme, -extreme, 0.0f); index++;
01829         push_point( extreme, -extreme, 0.0f); index++;
01830         push_point(-extreme,  extreme, 0.0f); index++;
01831         push_point( extreme,  extreme, 0.0f); index++;
01832     }
01833 
01834     /*  min x...max x vertices  */ 
01835     {
01836         /*  min z :  min_x...max_x  */ 
01837         {
01838             make_polygon(0, 1);
01839         }
01840         {
01841             int z;
01842             int range = (positive_cell_count - 1);
01843 
01844             for(z = -range; z <= range; ++z)
01845             {
01846                 float   z_position = (float)(z) * cell_width;
01847                 int     v0 = index++;
01848                 int     v1 = index++;
01849                 push_point(-extreme, z_position, 0.0f);
01850                 push_point( extreme, z_position, 0.0f);
01851                 make_polygon(v0, v1);
01852             }
01853         }
01854 
01855         /*  max z :  min_x...max_x  */ 
01856         {
01857             make_polygon(2, 3);
01858         }
01859     }
01860 
01861     /*  min z...max z vertices  */ 
01862     {
01863         /*  min x :  min_z...max_z  */ 
01864         {
01865             make_polygon(0, 2);
01866         }
01867 
01868         {
01869             int x;
01870             int range = (positive_cell_count - 1);
01871 
01872             for(x = -range; x <= range; ++x)
01873             {
01874                 float   x_position = (float)(x) * cell_width;
01875                 int     v0 = index++;
01876                 int     v1 = index++;
01877                 push_point(x_position, -extreme, 0.0f);
01878                 push_point(x_position,  extreme, 0.0f);
01879                 make_polygon(v0, v1);
01880             }
01881         }
01882 
01883         /*  max x :  min_z...max_z  */ 
01884         {
01885             make_polygon(1, 3);
01886         }
01887     }
01888 
01889     /*  Done  */ 
01890     build_mesh_from_geometry();
01891 }
01892 
01893 }
01894 
01895 
01896 }
01897 
Generated on Sun Apr 11 12:23:08 2010 for RenderStack by  doxygen 1.6.3