MeshFaces.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright © 2009, 2010 James Legg.
00006     This program is free software: you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation, either version 3 of the License, or
00009     (at your option) any later version.
00010 */
00011 
00012 #include "MeshFaces.h"
00013 
00014 #include "../stream_loader.h"
00015 #include <Debug.h>
00016 
00017 #include <fstream>
00018 #include <LinearMath/btMatrix3x3.h>
00019 
00020 namespace Track
00021 {
00022 
00023 MeshFaces::FaceVertex::FaceVertex()
00024 {
00025 }
00026 
00027 MeshFaces::FaceVertex::FaceVertex(std::size_t vertex_index)
00028     :   vertex_index(vertex_index)
00029 {
00030 }
00031 
00032 MeshFaces::Face::Face()
00033 {
00034 }
00035 
00036 MeshFaces::Face::Face(std::size_t v1, std::size_t v2, std::size_t v3)
00037     :
00038     fv1(v1),
00039     fv2(v2),
00040     fv3(v3)
00041 {
00042 }
00043 
00044 MeshFaces::Face::Face(const FaceVertex & v1, const FaceVertex & v2, const FaceVertex & v3)
00045     :
00046     fv1(v1),
00047     fv2(v2),
00048     fv3(v3)
00049 {
00050 }
00051 
00052 MeshFaces::Edge::Edge(std::size_t v1, std::size_t v2)
00053     :
00054     v1(v1),
00055     v2(v2)
00056 {
00057 }
00058 
00059 bool MeshFaces::Edge::operator<(MeshFaces::Edge o) const
00060 {
00061     // arrange so we are comparing the elements regardless of order.
00062     std::size_t m_small, m_large;
00063     if (v1 < v2)
00064     {
00065         m_small = v1;
00066         m_large = v2;
00067     } else {
00068         m_small = v2;
00069         m_large = v1;
00070     }
00071     std::size_t o_small, o_large;
00072     if (o.v1 < o.v2)
00073     {
00074         o_small = o.v1;
00075         o_large = o.v2;
00076     } else {
00077         o_small = o.v2;
00078         o_large = o.v1;
00079     }
00080     if (m_small < o_small) return true;
00081     if (m_small > o_small) return false;
00082     if (m_large < o_large) return true;
00083     return false;
00084 }
00085 
00086 MeshFaces::FaceGraph::FaceGraph(const Face & face)
00087     :   Face(face)
00088 {
00089 }
00090 
00091 btVector3 MeshFaces::FaceGraph::to_face_coords(btVector3 world_coords) const
00092 {
00093     btVector3 local = world_coords - vertex_positions[0];
00094     return btVector3(world_to_face.tdotx(local),
00095                      world_to_face.tdoty(local),
00096                      world_to_face.tdotz(local));
00097 }
00098 
00099 btVector3 MeshFaces::FaceGraph::to_world_coords(btVector3 face_coords) const
00100 {
00101     btVector3 local = btVector3(face_to_world.tdotx(face_coords),
00102                                 face_to_world.tdoty(face_coords),
00103                                 face_to_world.tdotz(face_coords));
00104     return  local + vertex_positions[0];
00105 }
00106 
00107 void MeshFaces::FaceGraph::set_conversions()
00108 {
00109     face_to_world = btMatrix3x3(edges[0].x(), edges[0].y(), edges[0].z(),
00110                                 edges[1].x(), edges[1].y(), edges[1].z(),
00111                                 face_normal.x(), face_normal.y(), face_normal.z());
00112     world_to_face = face_to_world.inverse();
00113     edge_line_segments[0] = Line(vertex_positions[0], vertex_positions[1]);
00114     edge_line_segments[1] = Line(vertex_positions[1], vertex_positions[2]);
00115     edge_line_segments[2] = Line(vertex_positions[2], vertex_positions[0]);
00116     for (int i = 0; i < 3; i++)
00117     {
00118         edge_planes[i] = edge_line_segments[i].get_plane_including(face_normal);
00119     }
00120     
00121     face_plane = Plane(face_normal, -face_normal.dot(vertex_positions[0]));
00122 }
00123 
00124 btVector3 MeshFaces::FaceGraph::find_nearest_point(btVector3 position) const
00125 {
00126     for (int i = 0; i < 3; i++)
00127     {
00128         if (!edge_planes[i].find_side(position))
00129         {
00130             // outside, find nearest point on the line segment.
00131             return edge_line_segments[i].closest_point_segment(position);
00132         }
00133     }
00134     // On the inside of the triangle.
00135     // Find the nearest point to the plane, because that is the nearest point.
00136     return face_plane.find_nearest_point(position);
00137 }
00138 
00139 MeshFaces::MeshFaces()
00140 {
00141 }
00142 
00143 MeshFaces::MeshFaces(std::istream & source)
00144 {
00145     load_from_stream(source);
00146 }
00147 
00148 MeshFaces::MeshFaces(std::string & filename)
00149 {
00150     std::ifstream file(filename.c_str());
00151     load_from_stream(file);
00152 }
00153 
00154 void MeshFaces::load_from_stream(std::istream & source)
00155 {
00156     DEBUG_MESSAGE("Loading Track::MeshFaces from stream.");
00157     
00158     std::size_t number_of_vertices;
00159     source >> number_of_vertices;
00160     DEBUG_MESSAGE("Loading " << number_of_vertices << " verticies. Now at "  << source.tellg());
00161     vertices_position.reserve(number_of_vertices);
00162     for(unsigned int i = 0; i < number_of_vertices; i++)
00163     {
00164         btScalar x, y, z;
00165         source >> x >> y >> z;
00166         vertices_position.push_back(btVector3(x, y, z));
00167         bounds |= btVector3(x, y, z);
00168     } 
00169     
00170     std::size_t number_of_faces;
00171     source >> number_of_faces;
00172     DEBUG_MESSAGE("Loading " << number_of_faces << " faces. Now at " << source.tellg());
00173     faces.reserve(number_of_faces);
00174     for(unsigned int f = 0; f < number_of_faces; f++)
00175     {
00176         FaceVertex fvs[3];
00177         for (unsigned int i = 0; i < 3; i++)
00178         {
00179             // vertex normal
00180             btScalar x, y, z;
00181             source >> x >> y >> z;
00182             fvs[i].normal = btVector3(x, y, z);
00183             
00184             // texture coordinates
00185             source >> fvs[i].texture_coord_u;
00186             source >> fvs[i].texture_coord_v;
00187             
00188             // vertex position index in vertices_position array.
00189             source >> fvs[i].vertex_index;
00190         }
00191         add_face(Face(fvs[0], fvs[1], fvs[2]));
00192     }
00193     DEBUG_MESSAGE("Finished loading Track::MeshFaces. Now at " << source.tellg());
00194 }
00195 
00196 MeshFaces::~MeshFaces()
00197 {
00198 }
00199 
00200 btVector3 MeshFaces::get_vertex_pos(std::size_t index) const
00201 {
00202     assert(index < vertices_position.size()); 
00203     return vertices_position[index];
00204 }
00205 
00206 void MeshFaces::add_vertex(const btVector3 & position)
00207 {
00208     vertices_position.push_back(position);
00209     bounds |= position;
00210 }
00211 
00212 std::size_t MeshFaces::get_num_vertices() const
00213 {
00214     return vertices_position.size();
00215 }
00216     
00217 const MeshFaces::Face & MeshFaces::get_face(std::size_t index) const
00218 {
00219     assert(index < faces.size());
00220     return faces[index];
00221 }
00222 
00223 std::vector<MeshFaces::Edge> MeshFaces::get_edges_for_face(std::size_t face_index) const
00224 {
00225     assert(face_index < faces.size());
00226     const Face & face = faces[face_index];
00227     
00228     std::vector<MeshFaces::Edge> result;
00229     result.reserve(3);
00230     result.push_back(Edge(face.fv1.vertex_index, face.fv2.vertex_index));
00231     result.push_back(Edge(face.fv2.vertex_index, face.fv3.vertex_index));
00232     result.push_back(Edge(face.fv3.vertex_index, face.fv1.vertex_index));
00233     return result;
00234 }
00235 
00236 void MeshFaces::add_face(std::size_t v1, std::size_t v2, std::size_t v3)
00237 {
00238     add_face(Face(v1, v2, v3));
00239 }
00240 
00241 void MeshFaces::add_face(MeshFaces::Face face)
00242 {
00243     std::size_t face_index = faces.size();
00244     faces.push_back(face);
00245 }
00246 
00247 void MeshFaces::add_edge(std::size_t v1, std::size_t v2, std::size_t face_index,
00248               std::map<EdgeGraph, std::size_t> & edge_to_face,
00249               std::vector<std::pair<std::size_t, std::size_t> > & graph_edges,
00250               std::vector<EdgeGraph> & edge_properties) const
00251 {
00252     EdgeGraph edge(v1, v2);
00253     std::pair<std::map<EdgeGraph, std::size_t>::iterator, bool> it(
00254             edge_to_face.insert(std::pair<EdgeGraph, std::size_t>(edge, face_index))
00255         );
00256     if (!it.second)
00257     {
00258         // already used by one face.
00259         // add to list of graph edges.
00260         graph_edges.push_back(
00261                                 std::pair<std::size_t, std::size_t>
00262                                 (edge_to_face[edge], face_index)
00263                              );
00264         // find other edge data.
00265         edge.v1_pos = vertices_position[v1];
00266         edge.v2_pos = vertices_position[v2];
00267         edge.length = (edge.v1_pos - edge.v2_pos).length();
00268         
00269         edge_properties.push_back(edge);
00270     }
00271 }
00272 
00273 std::size_t MeshFaces::get_number_of_faces() const
00274 {
00275     return faces.size();
00276 }
00277 
00278 MeshFaces::Graph MeshFaces::get_connectivity() const
00279 {
00280     // Find the shared edges. An edge should belong to only one face or two.
00281     // We take the index of the first face we find using an edge and store it
00282     // When we find another face using the same edge, this edge needs to be
00283     // inserted into a graph of the edges.
00284     std::map<EdgeGraph, std::size_t> edge_to_face;
00285     std::vector<std::pair<std::size_t, std::size_t> > graph_edges;
00286     std::vector<EdgeGraph> edge_properties;
00287     std::size_t face_index = 0;
00288     for (std::vector<Face>::const_iterator face_it = faces.begin();
00289          face_it != faces.end();
00290          face_it++, face_index++)
00291     {
00292         // find the 3 edges
00293         add_edge(face_it->fv1.vertex_index, face_it->fv2.vertex_index,
00294                  face_index,
00295                  edge_to_face, graph_edges, edge_properties);
00296         add_edge(face_it->fv2.vertex_index, face_it->fv3.vertex_index,
00297                  face_index,
00298                  edge_to_face, graph_edges, edge_properties);
00299         add_edge(face_it->fv3.vertex_index, face_it->fv1.vertex_index,
00300                  face_index,
00301                  edge_to_face, graph_edges, edge_properties);
00302     }
00303     // create a graph from the list of faces sharing an edge.
00304     Graph result(graph_edges.begin(), graph_edges.end(), edge_properties.begin(),
00305                   faces.size());
00306     assert(boost::num_vertices(result) == faces.size());
00307     assert(boost::num_edges(result) == graph_edges.size());
00308     typedef boost::graph_traits<Graph>::vertex_iterator VertexIterator;
00309     std::pair<VertexIterator, VertexIterator> vp = boost::vertices(result);
00310     for (std::vector<Face>::const_iterator face_it = faces.begin();
00311          vp.first != vp.second;
00312          ++vp.first, face_it++)
00313     {
00314         Graph::vertex_descriptor v = *vp.first;
00315         FaceGraph & face_graph = result[v];
00316         // copy information about the face to the graph.
00317         face_graph = FaceGraph(*face_it);
00318         // add additional data about the face.
00319         face_graph.vertex_positions[0] = vertices_position[face_it->fv1.vertex_index];
00320         face_graph.vertex_positions[1] = vertices_position[face_it->fv2.vertex_index];
00321         face_graph.vertex_positions[2] = vertices_position[face_it->fv3.vertex_index];
00322         face_graph.face_centre = (face_graph.vertex_positions[0] +
00323                                   face_graph.vertex_positions[1] +
00324                                   face_graph.vertex_positions[2]) / 3.0;
00325         face_graph.edges[0] = face_graph.vertex_positions[1] - face_graph.vertex_positions[0];
00326         face_graph.edges[1] = face_graph.vertex_positions[2] - face_graph.vertex_positions[0];
00327         face_graph.face_normal = face_graph.edges[0].cross(face_graph.edges[1]).normalized();
00328         face_graph.set_conversions();
00329     }
00330     return result;
00331 }
00332 
00333 MeshFaces::VertexGraph MeshFaces::get_vertex_graph()
00334 {
00335     VertexGraph result;
00336     // add vertex positions.
00337     for (std::vector<btVector3>::iterator it = vertices_position.begin();
00338          it != vertices_position.end();
00339          it++)
00340     {
00341         boost::add_vertex(*it, result);
00342     }
00343     // add edges
00344     for (std::vector<Face>::iterator it = faces.begin();
00345          it != faces.end();
00346          it++)
00347     {
00348 #define do_edge(v1, v2)\
00349         boost::add_edge(it->fv##v1.vertex_index, it->fv##v2.vertex_index,\
00350                         FaceEdgePointers(&(*it), &(it->fv##v1), &(it->fv##v2),\
00351                                          vertices_position[it->fv##v1.vertex_index].distance(vertices_position[it->fv##v2.vertex_index])),\
00352                         result)
00353         do_edge(1,2);
00354         do_edge(2,3);
00355         do_edge(3,1);
00356 #undef do_edge
00357     }
00358     return result;
00359 }
00360 
00361 void MeshFaces::copy_faces(const MeshFaces & other)
00362 {
00363     faces = other.faces;
00364     // Set normals for each face vertex.
00365     for (std::vector<Face>::iterator it = faces.begin(); it != faces.end(); it++)
00366     {
00367         // solid shading: face normals are consistant across a face
00368         btVector3 & v1 = vertices_position[it->fv1.vertex_index];
00369         btVector3 & v2 = vertices_position[it->fv2.vertex_index];
00370         btVector3 & v3 = vertices_position[it->fv3.vertex_index];
00371         btVector3 n = (v2-v1).cross(v3-v1).normalize();
00372         it->fv1.normal = n;
00373         it->fv2.normal = n;
00374         it->fv3.normal = n;
00376     }
00377 }
00378 
00379 void MeshFaces::add_faces(btTriangleMesh & shape) const
00380 {
00381     for (std::vector<Face>::const_iterator it = faces.begin(); it != faces.end(); it++)
00382     {
00383         btVector3 verts[3];
00384 #define face_vertex( index, vert ) \
00385         verts[index] = vertices_position[vert.vertex_index]
00386         
00387         face_vertex(0, it->fv1);
00388         face_vertex(1, it->fv2);
00389         face_vertex(2, it->fv3);
00390 #undef face_vertex
00391         shape.addTriangle(verts[2], verts[1], verts[0]);
00392     }
00393 }
00394 
00395 AxisAlignedBoundingBox MeshFaces::get_bounds() const
00396 {
00397     return bounds;
00398 }
00399 
00400 void MeshFaces::merge_doubles(btScalar distance2)
00401 {
00402     // Check each vertex against each vertex before it.
00403     // If the distances are too small, remember a substitution.
00404     std::size_t offset(0);
00405     std::map<std::size_t, std::size_t> substitutions;
00406     std::set<std::size_t> deletion_queue;
00407     for(std::size_t search_index = 0;
00408         search_index < vertices_position.size();
00409         search_index++)
00410     {
00411         bool provided_substitution = false;
00412         for(std::size_t compare_index = 0;
00413             compare_index < search_index;
00414             compare_index++)
00415         {
00416             if (vertices_position[search_index].distance2(vertices_position[compare_index]) < distance2)
00417             {
00418                 // Always use the lower numbered vertex, so we don't need 
00419                 // change substitutions for vertices already scanned.
00420                 // Use one extra layer of substitution, this corrects offset
00421                 // adjustments and merging into a vertex already merged.
00422                 substitutions[search_index] = substitutions[compare_index];
00423                 provided_substitution = true;
00424                 deletion_queue.insert(search_index);
00425                 // Now all later vertices will need a lower number.
00426                 offset++;
00427                 // We only merge one at a time, so don't look for more.
00428                 break;
00429             }
00430         }
00431         // substitute for a lower number since preceeding vertices will
00432         // be deleted, unless we already made a substitution.
00433         if (!provided_substitution)
00434         {
00435             // We do this even if offset is 0 to make a 1-1 mapping, where
00436             // we don't need to check if a substitution has been made before
00437             // using it.
00438             substitutions[search_index] = search_index - offset;
00439         }
00440     }
00441     if (offset > 0)
00442     {
00443         // Make the substitutions.
00444         for (std::vector<Face>::iterator it = faces.begin();
00445              it != faces.end(); it++)
00446         {
00447             std::map<std::size_t, std::size_t>::iterator sub_it;
00448             #define do_vert(vertex_number)\
00449             sub_it = substitutions.find(it->fv##vertex_number.vertex_index);\
00450             it->fv##vertex_number.vertex_index = sub_it->second;
00451             
00452             do_vert(1);
00453             do_vert(2);
00454             do_vert(3);
00455             #undef do_vert
00456         }
00457         
00458         // delete vertices no longer needed.
00459         for (std::set<std::size_t>::reverse_iterator it = deletion_queue.rbegin();
00460              it != deletion_queue.rend();
00461              it++)
00462         {
00463             vertices_position.erase(vertices_position.begin() + *it);
00464         }
00465     }
00466     // bounds may become minimally smaller, but we don't bother checking.
00467 }
00468 
00469 void MeshFaces::operator|=(const MeshFaces & source)
00470 {
00471     // New faces will have a different vertex indecies, depening on how many
00472     // we already have.
00473     std::size_t offset = vertices_position.size();
00474     
00475     // Add vertices on the end of the list.
00476     vertices_position.insert(vertices_position.end(),
00477                              source.vertices_position.begin(),
00478                              source.vertices_position.end());
00479     
00480     // expand bounds to include these new vertices.
00481     bounds |= source.bounds;
00482     
00483     // copy the faces in, but change their vertex indices using the offset.
00484     for (std::vector<Face>::const_iterator it = source.faces.begin();
00485          it != source.faces.end();
00486          it++)
00487     {
00488         Face f = *it;
00489         f.fv1.vertex_index += offset;
00490         f.fv2.vertex_index += offset;
00491         f.fv3.vertex_index += offset;
00492         // because we use add_face, edges and graph_edges are updated.
00493         add_face(f);
00494     }
00495 }
00496 
00497 void MeshFaces::set_source(bool is_edge, unsigned long int object_name)
00498 {
00499     for (std::vector<Face>::iterator it = faces.begin();
00500          it != faces.end();
00501          it++)
00502     {
00503         it->is_edge = is_edge;
00504         it->object_name = object_name;
00505     }
00506 }
00507 
00508 }

Get Racer at SourceForge.net. Fast, secure and Free Open Source software downloads

Generated at Mon Sep 6 00:41:11 2010 by Doxygen version 1.4.7 for Racer version svn335.