Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #include <rve_mesh_loader/stl_parser.h>
00031 #include <ros/console.h>
00032 
00033 #include <rve_msgs/Mesh.h>
00034 
00035 #include <Eigen/Geometry>
00036 
00037 namespace rve_mesh_loader
00038 {
00039 
00040 void calculateUV(const Eigen::Vector3f& vec, float& u, float& v)
00041 {
00042   Eigen::Vector3f pos(vec);
00043   pos.normalize();
00044   u = acos( pos.y() / pos.norm() );
00045 
00046   float val = pos.x() / ( sin( u ) );
00047   v = acos( val );
00048 
00049   u /= M_PI;
00050   v /= M_PI;
00051 }
00052 
00053 void parseSTL(uint8_t* buffer, size_t buffer_size, const std::string& extension, rve_msgs::Mesh& out_mesh)
00054 {
00055   out_mesh.submeshes.resize(1);
00056   rve_msgs::SubMesh& submesh = out_mesh.submeshes[0];
00057   uint8_t* pos = buffer;
00058   pos += 80; 
00059 
00060   uint32_t tri_count = *(uint32_t*)pos;
00061   pos += 4;
00062 
00063   submesh.positions.resize(tri_count * 3);
00064   submesh.normals.resize(tri_count * 3);
00065   submesh.indices.resize(tri_count * 3);
00066   submesh.tex_coords.resize(1);
00067   submesh.tex_coords[0].array.resize(tri_count * 3);
00068   submesh.tex_coords[0].dims = 2;
00069   for ( uint32_t tri = 0; tri < tri_count; ++tri )
00070   {
00071     
00072     Eigen::Vector3f normal;
00073 
00074     normal.x() = *(float*)pos;
00075     pos += 4;
00076     normal.y() = *(float*)pos;
00077     pos += 4;
00078     normal.z() = *(float*)pos;
00079     pos += 4;
00080 
00081     
00082     for (uint32_t i = 0; i < 3; ++i)
00083     {
00084       uint32_t vert_index = tri * 3 + i;
00085       rve_msgs::Vector3& p = submesh.positions[vert_index];
00086       p.x = *(float*)pos;
00087       pos += 4;
00088       p.y = *(float*)pos;
00089       pos += 4;
00090       p.z = *(float*)pos;
00091       pos += 4;
00092 
00093       rve_msgs::TexCoord& uvw = submesh.tex_coords[0].array[vert_index];
00094       calculateUV( Eigen::Vector3f(p.x, p.y, p.z), uvw.uvw[0], uvw.uvw[1] );
00095     }
00096 
00097     
00098     
00099     pos += 2;
00100 
00101     
00102 
00103     if (normal.squaredNorm() < 0.001)
00104     {
00105       rve_msgs::Vector3& p0 = submesh.positions[0];
00106       rve_msgs::Vector3& p1 = submesh.positions[1];
00107       rve_msgs::Vector3& p2 = submesh.positions[2];
00108       Eigen::Vector3f side1 = Eigen::Vector3f(p0.x, p0.y, p0.z) - Eigen::Vector3f(p1.x, p1.y, p1.z);
00109       Eigen::Vector3f side2 = Eigen::Vector3f(p1.x, p1.y, p1.z) - Eigen::Vector3f(p2.x, p2.y, p2.z);
00110       normal = side1.cross(side2);
00111       normal.normalize();
00112     }
00113 
00114     
00115     for (uint32_t i = 0; i < 3; ++i)
00116     {
00117       uint32_t vert_index = tri * 3 + i;
00118       rve_msgs::Vector3& n = submesh.normals[vert_index];
00119       n.x = normal.x();
00120       n.y = normal.y();
00121       n.z = normal.z();
00122     }
00123   }
00124 }
00125 
00126 }